Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 缓冲区未写入FileChannel的原因_Java_Nio_Filechannel - Fatal编程技术网

Java 缓冲区未写入FileChannel的原因

Java 缓冲区未写入FileChannel的原因,java,nio,filechannel,Java,Nio,Filechannel,我现在正在学习java NIO,我找到了一个示例来解释FileChannel的聚集操作,如下所示: public class ScattingAndGather { public static void main(String args[]) { gather(); } public static void gather() { ByteBuffer header = ByteBuffer.allocate(10); By

我现在正在学习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
对象时,它们从位置0开始。每当您向它们添加内容时,它们的位置都会前进,这意味着当您尝试将它们写出时,它们报告为不再有字节可读取。因此,在进行任何此类操作之前,您需要以某种方式重置其位置

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

翻转此缓冲区。将限制设置为当前位置,然后 该位置设置为零。如果标记已定义,则为 丢弃

在一系列通道读取或放置操作之后,调用此方法 准备一系列通道写入或相对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();
    }
}