FIleChannel、ByteBuffer 为何读取后位置为 0?

问题描述 投票:0回答:1
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。好像我什么也没读?

java bytebuffer filechannel
1个回答
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
的调用。

© www.soinside.com 2019 - 2024. All rights reserved.