为什么缓冲区没有被写入 FileChannel

我现在正在学习java NIO,我找到了一个例子来解释FileChannel的收集操作,如下所示:


public class ScattingAndGather {

    public static void main(String args[]) {

        gather();

    }


    public static void gather() {

        ByteBuffer header = ByteBuffer.allocate(10);

        ByteBuffer body = ByteBuffer.allocate(10);


        byte[] b1 = { '0', '1' };

        byte[] b2 = { '2', '3' };

        header.put(b1);

        body.put(b2);


        ByteBuffer[] buffs = { header, body };


        FileOutputStream os = null;

        FileChannel channel = null;

        try {

            os = new FileOutputStream("d:/scattingAndGather.txt");

            channel = os.getChannel();

            channel.write(buffs);

        } catch (IOException e) {

            e.printStackTrace();

        } finally {

            if (os != null) {

                try {

                    os.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }


            if (channel != null) {

                try {

                    channel.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

    }

}

虽然结果显示文件已经创建,但它是空的,应该是0123,这个例子有什么问题?


慕田峪9158850
浏览 226回答 1
1回答

至尊宝的传说

出现问题的原因是您从未重置缓冲区的位置。当您创建两个ByteBuffer对象时,它们从位置零开始。每当您向其中添加内容时,它们的位置都会前进,这意味着当您尝试将它们写出时,它们会报告没有更多字节可供读取。因此,在进行任何此类操作之前,您需要以某种方式重置它们的位置。Buffer提供了几种最容易使用的方法flip()。正如您在此处的文档中所见,其用法如下:翻转这个缓冲区。将限制设置为当前位置,然后将位置设置为零。如果定义了标记,则将其丢弃。在一系列通道读取或放置操作之后,调用此方法以准备一系列通道写入或相关获取操作因此,在写出它们之前,您需要翻转它们。此外,由于您正在试验,java.nio我不明白为什么您不应该使用try with resources语句来管理您的各种资源。这样,您将避免关闭可以手动自动关闭的资源的过多样板代码。使用这些你的代码可以显着缩小并且更具可读性:public static void gather() {    ByteBuffer header = ByteBuffer.allocate(10);    ByteBuffer body = ByteBuffer.allocate(10);    byte[] b1 = { '0', '1' };    byte[] b2 = { '2', '3' };    header.put(b1);    body.put(b2);    //flip buffers before writing them out.    header.flip();    body.flip();    ByteBuffer[] buffs = { header, body };    try(FileOutputStream os = new  FileOutputStream("d:/scattingAndGather.txt"); FileChannel channel = os.getChannel()) {    channel.write(buffs);    } catch (IOException e) {        e.printStackTrace();    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java