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
in.write(buffer);
System.out.println(buffer); //[pos=5 lim=5 cap=1000]
// flip for reading
buffer.flip();
System.out.println(buffer); //[pos=0 lim=5 cap=1000]
// read
in.read(buffer); // [pos=0 lim=5 cap=1000] why pos=0 not pos=5? I didn't read anything?
System.out.println(buffer);
// flip for writing
buffer.flip();
System.out.println(buffer); //[pos=0 lim=0 cap=1000] so I write nothing to out
out.write(buffer);
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
}
}
你能解释一下为什么读后的 pos 是 0 而不是 5 吗?我想向 in 写入“Hello”,然后从 in 读取并将“Hello”写入 out。但我不明白为什么读完之后pos是0。就像我什么都没读过一样。
我尝试向 in 写入“Hello”,然后从 in 读取,最后写入 out。但我不明白为什么读取后缓冲区的位置= 0。好像我什么也没读?
您的
FileChannel
对象 (in
) 是一个通道,它本身有一个位置。这个想法是,在拨打in.write(buffer)
之后,您可以..再拨打in.write(buffer)
一些。您的问题意味着您认为 FileChannel
上的每个方法调用都是独立的,并经历实际要求操作系统打开文件的整个过程,然后执行方法调用暗示的操作(读取或写入),然后关闭it - 每个方法调用都是独立的,并且独立于所有其他方法。
不是这样的。
创建FileChannel的行为打开了操作系统级别的资源,所有方法调用都会相互影响。当您调用
write
时,FileChannel 现在位于新文件中的 位置 5。然后,当您调用 read 时,显然,您什么也得不到: FileChannel
位于文件末尾,因此没有要读取的字节。
要么关闭频道并打开一个新频道,要么使用
position
来回跳转:添加对 in.position(0L)
after 调用 in.write
和 before 调用 in.read
的调用。