代码之家  ›  专栏  ›  技术社区  ›  gesanri

为什么缓冲区没有写入FileChannel

  •  2
  • gesanri  · 技术社区  · 6 年前

    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 回复  |  直到 6 年前
        1
  •  2
  •   akourt    6 年前

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

    当您创建 ByteBuffer

    Buffer 提供了几种最易于使用的方法 flip() . 正如您在文档中看到的 here ,其用法如下:

    翻转此缓冲区。将限制设置为当前位置,然后 丢弃的。

    准备一系列通道写入或相对get操作

    因此,在写出来之前,你需要把它们翻过来。而且,既然你在试验 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();
        }
    }