为何FileChannel读取后ByteBuffer的position仍为0?
问题原因及解决方法
核心原因
你遇到的问题本质是FileChannel的文件指针位置没有重置:
- 当你通过
in.write(buffer)把"Hello"写入文件后,FileChannel的文件指针已经移动到了文件末尾(第5字节位置)。 - 此时直接调用
in.read(buffer),会从当前指针位置(文件末尾)读取数据,没有可读内容,read()返回0,ByteBuffer的position自然保持0不变。 - 后续调用
buffer.flip()会把limit设为当前position(0),导致写入out.txt时没有数据可写。
关键错误点
- 忽略FileChannel的指针位置:ByteBuffer的flip操作只影响自身的读写模式,不会改变FileChannel的文件指针位置。写入完成后必须手动重置文件指针到开头,才能读取刚写入的内容。
- 读取后的ByteBuffer处理:读取成功后需要调用flip切换到写模式,才能把buffer内容写入out.txt。
修正后的代码
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class CodingDecoding { public static void main(String[] args) { try ( FileChannel out = FileChannel.open(Paths.get("out.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE); FileChannel in = FileChannel.open(Paths.get("in.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE); ) { // write "Hello" to buffer and flip to make buffer ready for writing ByteBuffer buffer = ByteBuffer.allocate(1000); buffer.put("Hello".getBytes()); System.out.println(buffer); // [pos=5 lim=1000 cap=1000] buffer.flip(); System.out.println(buffer); // [pos=0 lim=5 cap=1000] // write to in.txt in.write(buffer); System.out.println(buffer); //[pos=5 lim=5 cap=1000] // 重置FileChannel的文件指针到文件开头,这是关键! in.position(0); // 清空buffer,准备读取 buffer.clear(); System.out.println(buffer); //[pos=0 lim=1000 cap=1000] // 读取in.txt内容到buffer int readBytes = in.read(buffer); System.out.println("读取字节数:" + readBytes); // 输出5 System.out.println(buffer); //[pos=5 lim=1000 cap=1000] // flip切换到写模式,准备写入out.txt buffer.flip(); System.out.println(buffer); //[pos=0 lim=5 cap=1000] out.write(buffer); } catch (IOException ioException) { ioException.printStackTrace(); } } }
额外说明
in.position(0):强制将FileChannel的文件指针移到文件起始位置,确保能读取到刚写入的内容。buffer.clear():将ByteBuffer重置为写模式(pos=0,lim=cap),准备接收读取的数据;也可以用flip(),但clear更适合准备读取的场景。- 读取后调用
buffer.flip():将buffer从读模式切换到写模式,让out.write()能读取到buffer中的有效数据(从pos=0到lim=5)。
内容的提问来源于stack exchange,提问作者wydra__
相关产品推荐
相关产品推荐

