【问题标题】:Java Inputstream too slow to read 1.5mb fileJava Inputstream 读取 1.5mb 文件太慢
【发布时间】:2016-10-06 00:21:27
【问题描述】:

我正在处理一个项目的一部分。对于我这样的新手来说,它相当大。在一个部分中,我必须从电子邮件中获取附件并将​​其保存到系统文件中。但是由于某种原因,它花费了太长时间。我将此代码用于第一种方法:

byte[] buf = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buf)) != -1) {
    fileOutputStream.write(buf, 0, bytesRead);
}

对于一个 1.5Mb 的文件,这个代码块大约需要 86 秒。但是当我尝试从示例测试项目中运行相同的代码时,它在几毫秒内完成(为此,我采用了系统文件的输入流而不是附件,然后将其写入另一个目录)。 我已经访问过这个页面: Java: InputStream too slow to read huge files

Input stream reads large files very slowly, why?

但我无法找出具体原因。 我尝试通过这种方法对其进行更多调试:

InputStream inputStream = bodyPart.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
long tStart = System.currentTimeMillis();
byte[] buf = new byte[4096];
int bytesRead;
int i=1;
while(true)
{
    long tc = System.currentTimeMillis();
    bytesRead = inputStream.read(buf);
    long tc1 = System.currentTimeMillis();
    System.out.println("\nRead Time "+i+" ="+(tc1-tc));

    if(bytesRead==-1) break;
    fileOutputStream.write(buf, 0, bytesRead);

    long tc2 = System.currentTimeMillis();
    System.out.println("Write Time "+i+" ="+(tc2-tc1));
    i++;
}

long tEnd = System.currentTimeMillis();
long tDelta = tEnd - tStart;
System.out.println("\n\nTotal Time="+tDelta+"\n\n");

而且输出也很奇怪。 1.5Mb 文件的部分输出是:

Read Time 354 =788
Write Time 354 =0

Read Time 355 =0
Write Time 355 =0

Read Time 356 =0
Write Time 356 =0

Read Time 357 =744
Write Time 357 =0

Read Time 358 =0
Write Time 358 =0

Read Time 359 =0
Write Time 359 =0

Read Time 360 =837
Write Time 360 =0

Read Time 361 =0
Write Time 361 =0

Read Time 362 =1
Write Time 362 =0

Read Time 363 =811
Write Time 363 =0

Read Time 364 =1
Write Time 364 =0

Read Time 365 =0
Write Time 365 =0

Read Time 366 =757
Write Time 366 =0

Read Time 367 =1
Write Time 367 =0

Read Time 368 =0
Write Time 368 =0

Read Time 369 =736
Write Time 369 =0

Read Time 370 =0
Write Time 370 =0

Read Time 371 =0
Write Time 371 =0

Read Time 372 =484
Write Time 372 =0

Read Time 373 =0

Total Time=88796

在这里,您可以看到 4Kb 缓冲区的读取时间在每 3 步或读取之后需要很长时间。我无法弄清楚具体问题。我也使用过缓冲输入流和输出流,但结果是一样的。谁能帮我找出实际问题是什么?

【问题讨论】:

  • 这些附件是否存储在网络服务器上?网络服务器可能响应缓慢 - 您对此无能为力。
  • 其实我在问题中提到的代码上方下载了附件。所以我认为它应该在jvm内存中。 @SvetlinZarev
  • 如果你引用bodyPart.getInputStream();,那么它不在JVM内存中。
  • 检查硬盘活动
  • 你是否并行读取其他文件?

标签: java inputstream fileinputstream bufferedinputstream


【解决方案1】:

使用缓冲输入流而不是输入流。

【讨论】:

  • 我已经在问题中说过,我已经尝试过使用 buffredInputStream 并且结果是一样的。
  • A BufferedInputStream 只有在使用更大的缓冲区时才会产生影响。当前代码使用 4 KB 缓冲区。
  • 我在 64 位系统上将 bufferdInputStream 用于 4KB、8KB、32KB、1MB 缓冲区。我试图用不同的方法解决这个问题。但所有这些都花费了非常相似的时间。我在问题中给出了我最常用的方法。
  • BufferedInputStream 并不神奇。如果你查看它的源代码,你会发现它和 OP 的代码完全一样。
猜你喜欢
  • 2011-08-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2015-05-23
  • 1970-01-01
  • 2011-09-03
  • 2010-10-11
相关资源
最近更新 更多