为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕田峪9158850 2021-08-25 15:26:34
我现在正在学习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,这个例子有什么问题?
查看完整描述

1 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

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

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

    }

}


查看完整回答
反对 回复 2021-08-25
  • 1 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信