【问题标题】:Input stream reads large files very slowly, why?输入流读取大文件很慢,为什么?
【发布时间】:2014-04-29 21:06:53
【问题描述】:

我正在尝试提交一个 500 MB 的文件。 我可以加载它,但我想提高性能。 这是慢代码:

File dest = getDestinationFile(source, destination);
if(dest == null) return false;

in = new BufferedInputStream(new  FileInputStream(source));
out = new BufferedOutputStream(new  FileOutputStream(dest));
byte[] buffer = new byte[1024 * 20];
int i = 0;

// this while loop is very slow
while((i = in.read(buffer)) != -1){
   out.write(buffer, 0, i); //<-- SLOW HERE
   out.flush();
}

我怎样才能找到它慢的原因?
字节数组大小/缓冲区大小不够吗? 您有什么提高性能的想法吗?

提前感谢您的帮助

【问题讨论】:

  • 我会将out.flush() 移到循环之外,但无论如何代码对我来说看起来还不错......你叫什么“慢”?

标签: java file-upload file-io inputstream large-files


【解决方案1】:

您不应该在循环中刷新。 您正在使用 BufferedOutputStream。这意味着在“缓存”一些数据后,它会将数据刷新到文件中。 您的代码会在写入少量数据后刷新数据,从而降低性能。

尝试这样做:

while((i = in.read(buffer)) != -1){
out.write(buffer, 0, i); <-- SLOW HERE
}
out.flush();

..:: 编辑:回应下面的评论 ::..
在我看来,您根本不应该使用缓冲区。您正在使用 Buffered(Output/Input)Stream 这意味着他们有自己的缓冲区来从磁盘读取“包”数据并保存“包”数据。我不能 100% 确定使用额外缓冲区的性能,但我希望您展示我将如何做到这一点:

File dest = getDestinationFile(source, destination);
if(dest == null) return false;

in = new BufferedInputStream(new  FileInputStream(source));
out = new BufferedOutputStream(new  FileOutputStream(dest));

int i;
while((i = in.read()) != -1){
   out.write(i);
}
out.flush();

在我的版本中,您只会读取一个 BYTE(没有 int。阅读文档:
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read()
此方法返回 int 但这只是一个 BYTE)但无需读取整个缓冲区(因此您不必担心它的大小)。

或许您应该阅读有关流的更多信息,以更好地了解如何处理它们。

【讨论】:

  • 非常感谢你们两位,我将测试我的代码,顺便看看会发生什么,使用什么好的缓冲区大小?我不想使用太多,但同时也不要太少。原来是 byte[] buffer = new byte[1000] 看起来太小了。
  • 感谢您的意见。我对一件事感到困惑,如果我要删除 buffer[] 数组,如何在 out.write() 部分打印?它将创建一个错误,因为我之前创建的缓冲区数组不存在 File dest = getDestinationFile(source, destination); if(dest == null) 返回假; in = new BufferedInputStream(new FileInputStream(source)); out = new BufferedOutputStream(new FileOutputStream(dest)); while((i = in.read()) != -1){ out.write(buffer, 0, i);
  • 对不起:我在我的例子中犯了一个错误。不,它已被编辑,因此您可以对其进行测试
  • 感谢亚历克斯的回复...抱歉,来晚了!也感谢 sjuan76 抽出时间来帮助解决这个问题。
猜你喜欢
  • 2013-10-03
  • 2018-09-27
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多