我正在处理以下代码,用于将一个大文件拆分为一组较小的文件:
FileInputStream input = new FileInputStream(this.fileToSplit);
BufferedInputStream iBuff = new BufferedInputStream(input);
int i = 0;
FileOutputStream output = new FileOutputStream(fileArr[i]);
BufferedOutputStream oBuff = new BufferedOutputStream(output);
int buffSize = 8192;
byte[] buffer = new byte[buffSize];
while (true) {
if (iBuff.available() < buffSize) {
byte[] newBuff = new byte[iBuff.available()];
iBuff.read(newBuff);
oBuff.write(newBuff);
oBuff.flush();
oBuff.close();
break;
}
int r = iBuff.read(buffer);
if (fileArr[i].length() >= this.partSize) {
oBuff.flush();
oBuff.close();
++i;
output = new FileOutputStream(fileArr[i]);
oBuff = new BufferedOutputStream(output);
}
oBuff.write(buffer);
}
} catch (Exception e) {
e.printStackTrace();
}
这是我看到的奇怪行为...当我使用 3GB 文件运行此代码时,初始 iBuff.available() 调用返回一个大约 2,100,000,000 的值,并且代码工作正常。当我在 12GB 文件上运行此代码时,初始 iBuff.available() 调用仅返回 200,000,000 的值(该值小于分割文件大小 500,000,000,导致处理出错)。
我认为这种行为差异与它是在 32 位 Windows 上有关。我将对 4.5 GB 文件和 3.5 GB 文件运行更多测试。如果 3.5 文件有效而 4.5 文件无效,这将进一步证实这是 32 位与 64 位问题的理论,因为 4GB 将成为阈值。
最佳答案
如果您阅读了 javadoc,它会非常清楚地说明:
Returns the number of bytes that can be read from this input stream without blocking (emphasis added by me)
所以很明显,你想要的并不是这个方法提供的。因此,根据底层的InputStream,您可能会更早地遇到问题(例如,网络上的流与不返回文件大小的服务器 - 您必须读取完整的文件并缓冲它,只是为了返回“正确的”可用文件) () 计数,这会花费很多时间 - 如果您只想读取标题怎么办?)
因此,处理此问题的正确方法是更改解析方法,以便能够分段处理文件。就我个人而言,我认为没有太多理由在这里使用 available() - 只需调用 read() 并在 read() 返回 -1 后立即停止应该可以正常工作。如果您想确保每个文件确实包含 blockSize 字节,则可以变得更加复杂 - 如果该场景很重要,只需添加一个内部循环。
int blockSize = XXX;
byte[] buffer = new byte[blockSize];
int i = 0;
int read = in.read(buffer);
while(read != -1) {
out[i++].write(buffer, 0, read);
read = in.read(buffer);
}
关于Java:BufferedInputStream 的 available() 方法存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6164853/