Java 如何使用NIO将InputStream写入文件?
我正在使用以下方法将Java 如何使用NIO将InputStream写入文件?,java,image,file,inputstream,nio,Java,Image,File,Inputstream,Nio,我正在使用以下方法将输入流写入文件: private void writeToFile(InputStream stream) throws IOException { String filePath = "C:\\Test.jpg"; FileChannel outChannel = new FileOutputStream(filePath).getChannel(); ReadableByteChannel inChannel =
输入流
写入文件
:
private void writeToFile(InputStream stream) throws IOException {
String filePath = "C:\\Test.jpg";
FileChannel outChannel = new FileOutputStream(filePath).getChannel();
ReadableByteChannel inChannel = Channels.newChannel(stream);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(true) {
if(inChannel.read(buffer) == -1) {
break;
}
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
inChannel.close();
outChannel.close();
}
我想知道这是否是使用NIO的正确方法。我读过一个方法,它采用三个参数:
src
,没有位置
和计数
,是否有任何方法可以使用此方法创建文件
对于图像,是否有更好的方法仅从InputStream
和NIO创建图像
任何信息对我都非常有用。这里也有类似的问题,但我找不到任何适合我的情况的特定解决方案。不,这是不正确的。您有丢失数据的风险。规范的NIO复制循环如下所示:
while (in.read(buffer) >= 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
long offset = 0;
long quantum = 1024*1024; // or however much you want to transfer at a time
long count;
while ((count = out.transferFrom(in, offset, quantum)) > 0)
{
offset += count;
}
请注意已更改的循环条件,它负责在EOS刷新输出,以及使用compact()
代替clear(),
来处理短写的可能性
类似地,规范的transferTo()/transferFrom()
循环如下所示:
while (in.read(buffer) >= 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
long offset = 0;
long quantum = 1024*1024; // or however much you want to transfer at a time
long count;
while ((count = out.transferFrom(in, offset, quantum)) > 0)
{
offset += count;
}
它必须在循环中调用,因为它不能保证传输整个量子。我会使用Files.copy
Files.copy(is, Paths.get(filePath));
至于你的版本
ByteBuffer.allocateDirect
更快—Java将尽最大努力直接在其上执行本机I/O操作为什么这么复杂?您可以在一行中执行相同的操作:
Files.copy(流,新文件(“C:\\Test.jpg”).toPath()代码>transferFrom()
和transferTo()
必须在循环中调用。无法保证他们会转移请求的计数。这就是它们返回计数的原因。使用Files.copy(fileInputStream、filePath、StandardCopyOption.REPLACE_EXISTING);如果文件已存在。如果transferFrom返回0,则并不意味着所有字节都已实际传输。为了100%正确,我们需要提前知道InputStream和loop的预期计数,直到我们将它们全部传输。你同意吗?是的,我同意。奇怪的是,这些API没有正确的EOS指示。