我对Java NIO感到困惑

时间:2019-03-06 08:29:14

标签: java nio

我对java nio缓冲区和Files.write感到困惑,如果我可以在文件上写缓冲区和通道,为什么我需要Files类。

这两个工作代码示例之间有什么区别。

String newData = "New String to write to file..." + System.currentTimeMillis();

Path path = Paths.get("C://data/nio-data2.txt");
try {
    Files.write(path,newData.getBytes());
} catch (IOException e) {
    e.printStackTrace();
}

try {
    RandomAccessFile aFile = new RandomAccessFile("C://data/nio-data.txt", "rw");
    FileChannel channel = aFile.getChannel();
    ByteBuffer buf = ByteBuffer.allocate(48);
    buf.clear();
    buf.put(newData.getBytes());

    buf.flip();

    while(buf.hasRemaining()) {
        channel.write(buf);
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

编辑

我想再问一个问题,是Channels.newOutputStream在写入文件或作为非阻塞方式时会中断线程

2 个答案:

答案 0 :(得分:2)

版本Files较短且更易于理解。

其他版本更加灵活。当您只写入一个文件时,它不是很有用,但是如果您在不同的存储中有许多文件,则可以节省一些资源。

编辑

这是Files.write源代码:

public static Path write(Path path, byte[] bytes, OpenOption... options)
    throws IOException
{
    // ensure bytes is not null before opening file
    Objects.requireNonNull(bytes);

    try (OutputStream out = Files.newOutputStream(path, options)) {
        int len = bytes.length;
        int rem = len;
        while (rem > 0) {
            int n = Math.min(rem, BUFFER_SIZE);
            out.write(bytes, (len-rem), n);
            rem -= n;
        }
    }
    return path;
}

如您所见,它内部没有使用NIO,只有旧的OutputStream

编辑2

实际上Files.newOutputStream并没有返回我期望的FileOutputStream。它返回在OutputStream中定义的Channels.newOutputStream,该变量在内部使用NIO。

答案 1 :(得分:1)

  1. <myControls:DataGridLargeTextColumn Binding="{Binding SomeBinding}" ToolTipText="12345" ToolTipShowDuration="{Binding Data.ToolTipDuration, Source={StaticResource proxy}}" ToolTipWidth="{Binding Data.ToolTipMaxWidth, Source={StaticResource proxy}}"/> 使用<myControls:DataGridLargeTextColumn Binding="{Binding SomeBinding}" ToolTipText="{Binding SomeOtherPropertyBinding}" ToolTipShowDuration="{Binding Data.ToolTipDuration, Source={StaticResource proxy}}" ToolTipWidth="{Binding Data.ToolTipMaxWidth, Source={StaticResource proxy}}"/> 代替Files.write(...)。它有一些不同的机制,因此最好通过Google进行了解

  2. OutputStream更短,并且封装了写入文件的逻辑

  3. 使用此类“低级”代码时,您需要照顾很多事情。例如,在您的示例中,您没有关闭频道。

因此,总而言之,如果您只需要编写–最好使用RandomAccessFile.getChannel()或其他高级API。如果在读/写过程中需要一些“附加”功能,则需要使用Files.write(...)Files