我对 Java NIO 感到困惑
I'm Confused with Java NIO
我对 java nio 缓冲区感到困惑,Files.write
如果我可以使用文件上的缓冲区和通道写入,为什么我需要文件 class.
这两个工作代码示例之间有什么区别。
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在写入文件或作为非阻塞工作时中断线程
版本 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
并不returnFileOutputStream
如我所料。它 returns OutputStream
定义在 Channels.newOutputStream
里面使用 NIO。
Files.write(...)
使用 OutputStream
而不是 RandomAccessFile.getChannel()
。它有一些不同的机制,所以更好地google它来理解
Files.write(...)
写入文件的逻辑更短和封装
当你使用这样的'low'代码时,你需要注意很多事情。例如,在您的示例中,您没有关闭频道。
因此,总而言之,如果您只需要编写 – 最好使用 Files
或其他高级 API。如果在 read/write 期间需要某些 'additional' 功能,则需要使用 RandomAccessFile
或 InputStream/OutputStream
我对 java nio 缓冲区感到困惑,Files.write
如果我可以使用文件上的缓冲区和通道写入,为什么我需要文件 class.
这两个工作代码示例之间有什么区别。
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在写入文件或作为非阻塞工作时中断线程
版本 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
并不returnFileOutputStream
如我所料。它 returns OutputStream
定义在 Channels.newOutputStream
里面使用 NIO。
Files.write(...)
使用OutputStream
而不是RandomAccessFile.getChannel()
。它有一些不同的机制,所以更好地google它来理解Files.write(...)
写入文件的逻辑更短和封装当你使用这样的'low'代码时,你需要注意很多事情。例如,在您的示例中,您没有关闭频道。
因此,总而言之,如果您只需要编写 – 最好使用 Files
或其他高级 API。如果在 read/write 期间需要某些 'additional' 功能,则需要使用 RandomAccessFile
或 InputStream/OutputStream