通过一个通道及缓存区完成文件的读 写操作,通过本例代码验证了:
* 1 RandomAccessFile的指针与FileChannel 的指针是同步更新的,结果是一致的.
* 2 channel.position(channel.size()):从文件末尾追加内容,channel.position(0):从文件开头覆盖内容,可以指定0到channel.size() 之间的任意值以完成文件读写定位.
* 3 写入文件时,RandomAccessFile是以字节为单位写入,写入的字节覆盖源文件中多字节字符的部分字节后,文件将出现乱码.
* 4 channel.read(buffer) 对buffer来说是写入模式,channel.write(buffer)是读取模式,需要转换flip.
* 5 从buffer中读取数据时有两种方式,第二种方式可以有效避免buffer中的无效字节(0字节),详情见代码
static void readWriteFile() throws IOException {
try ( //可读写的通道
RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "rw");
FileChannel channel = randomAccessFile.getChannel()){
System.out.println("0 文件读写指针:" + randomAccessFile.getFilePointer());
System.out.println("0 channel指针:" + channel.position());
ByteBuffer buffer = ByteBuffer.allocate(1024);
System.out.println("读取数据:");
int size = 0;
//读取数据时,buffer是写入模式
while ((size = channel.read(buffer)) > 0) {
System.out.println("\t第一次读取到数据,字节数:" + size);
//取出buffer中的数据,buffer应该是读取模式,需要转换
buffer.flip();
System.out.println("\t提取数据方式一(buffer中的无效数据会转为空字符):");
byte[] array = buffer.array();
String s = new String(array, Charset.defaultCharset());
System.out.println(s);
System.out.println("\t提取数据方式二(仅转换了buffer中有效的部分):");
CharBuffer charBuffer = Charset.defaultCharset().decode(buffer);
System.out.println(charBuffer);
buffer.clear();
}
System.out.println();
System.out.println("1 文件读写指针:" + randomAccessFile.getFilePointer());
System.out.println("1 channel指针:" + channel.position());
/**
* 从文件头部写入数据(覆盖现有的数据)
* 有个很有意思的地方:写入的文件会出现乱码,因为覆盖数据是以字节为单位进行的,
* 当原文件中的多字节码字符其中的部分字节被覆盖时,就出现了乱码
*/
channel.position(0);
//从文件末尾追加数据
// channel.position(channel.size());
System.out.println("写入数据:");
//定义要写入的字节数组
byte[] bs = "aaa123".getBytes(StandardCharsets.UTF_8);
System.out.println(new String(bs, Charset.defaultCharset()));
buffer.clear();
buffer.put(bs);
//写入文件时,相当于从buffer中读数据,所以,需要 flip 一下.
buffer.flip();
channel.write(buffer);
System.out.println("2 文件读写指针:" + randomAccessFile.getFilePointer());
System.out.println("2 channel指针:" + channel.position());
}
}
文件中的内容为:
Hello!好好学习,天天向上!
Very Good !
从文件头部写入以下内容时,文件正常无乱码,6个字节正好替换了原文件中的 Hello!
aaa123
从文件头部写入以下内容时,文件出现乱码!
因为写入内容有7个字节,从头覆盖时,会将第一个"好"的第一个字节替换成4,导致"好"字编码失败,因而出现乱码.
aaa1234