复习
我们用下面一段代码来复习一下昨天学的内容
File dir = new File("E:\\Workspace\\IdeaStudio\\io-demo\\random-access-file\\demo");
if (!dir.exists()) {
dir.mkdir();
}
if (!dir.isDirectory()) {
System.out.println("新建目录出错");
}
File file = new File(dir, "file.dat");
if (!file.exists()) {
boolean rs1 = file.createNewFile();
if (!rs1) {
System.out.println("创建文件失败");
}
}
if (!file.isFile()) {
System.out.println("新建文件出错");
}
我们从构成方法开始
API
RandomAccessFile(File file, String mode)
创建一个随机访问文件流从File参数指定的文件中读取,并可选地写入文件。
RandomAccessFile(String name, String mode)
创建随机访问文件流,以从中指定名称的文件读取,并可选择写入文件。
我们关心一下这个参数 mode
:
Value Meaning "r" Open for reading only. Invoking any of the write methods of the resulting object will cause an IOException to be thrown. "rw" Open for reading and writing. If the file does not already exist then an attempt will be made to create it. "rws" Open for reading and writing, as with "rw", and also require that every update to the file's content or metadata be written synchronously to the underlying storage device. "rwd" Open for reading and writing, as with "rw", and also require that every update to the file's content be written synchronously to the underlying storage device.
大概是说有四种模式:"r"(只读)、"rw"(读写)、"rwd"、"rws"。
于是:
String mode = "rw";
RandomAccessFile randomAccessFile = new RandomAccessFile(file, mode);
写点东西
API
void write(int b)
将指定的字节写入此文件。
详细看一下:
public void write(int b)
throws IOException将指定的字节写入此文件。 写入从当前文件指针开始。
Specified by:
write在界面 DataOutput
参数
b - byte 。
异常
IOException - 如果发生I / O错误。
这里最重要的亮点:
1、参数:写进去一次一个字节(bye 8位)
2、指针
那怎么样把一个整数写进去呢?
int b = 0x7fffffff;
randomAccessFile.write(b >>> 24);
randomAccessFile.write(b >>> 16);
randomAccessFile.write(b >>> 8);
randomAccessFile.write(b);
System.out.println(randomAccessFile.getFilePointer());
测试结果:
0
4
Process finished with exit code 0
读一下
API
int read()
从该文件读取一个字节的数据。
int read(byte[] b)
从该文件读取最多 b.length字节的数据到字节数组。
byte[] c = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(c);
System.out.println(Arrays.toString(c));
项目经验
之前在写一个物联网网关短信平台的时候,数据传输就用到byte,那时候就需要对这一块熟悉,还好,网上参考资料比较多,复制粘贴下来,也能解决。我们来看一下:
public final void writeInt(int v) throws IOException {
write((v >>> 24) & 0xFF);
write((v >>> 16) & 0xFF);
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
//written += 4;
}
public final void writeLong(long v) throws IOException {
write((int)(v >>> 56) & 0xFF);
write((int)(v >>> 48) & 0xFF);
write((int)(v >>> 40) & 0xFF);
write((int)(v >>> 32) & 0xFF);
write((int)(v >>> 24) & 0xFF);
write((int)(v >>> 16) & 0xFF);
write((int)(v >>> 8) & 0xFF);
write((int)(v >>> 0) & 0xFF);
//written += 8;
}
public final void writeChars(String s) throws IOException {
int clen = s.length();
int blen = 2*clen;
byte[] b = new byte[blen];
char[] c = new char[clen];
s.getChars(0, clen, c, 0);
for (int i = 0, j = 0; i < clen; i++) {
b[j++] = (byte)(c[i] >>> 8);
b[j++] = (byte)(c[i] >>> 0);
}
writeBytes(b, 0, blen);
}
如果你在写项目的时候,有去看过大佬封装的Util,以上这些代码很眼熟吧,当然这些也是jdk大神提供给我们的。
编码
短信传输的编码是 UCS2
,这对中文来说无疑是要乱码的,那怎么办呢?
如果你也遇到这个问题,我相信你是痛苦的。
当时搜索了大量资料,请教了很多人,当然也有代码。解决方案是:直接转成 UTF-16BE
。
这是什么编码,听都没听过。
Java是双字节编码,就是UTF-16BE。
String s2 = "中";
randomAccessFile.writeChars(s2);
System.out.println(randomAccessFile.getFilePointer());
randomAccessFile.seek(0);
// 写进去了吗,读一下
byte[] c = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(c);
System.out.println(Arrays.toString(c));
String s1 = new String(c, "utf-16be");
System.out.println(s1);
randomAccessFile.close();
0
2
[78, 45]
中
Process finished with exit code 0
另外,文件都是byte。
资料
1、本节测试代码:random-access-file