繁体   English   中英

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

[英]why the buffers have not been write into the 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,这个例子有什么问题?

出现问题的原因是您从未重置缓冲区的位置。

当您创建两个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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM