我有一个使用以下代码通过TCP套接字接收文件的方法:
FileOutputStream fileStream = new FileOutputStream(filename.getName());
while (totalRead < size) {
if (size - totalRead > CHUNKSIZE) {
read = getInputStream().read(buffer, 0, CHUNKSIZE);
} else {
read = getInputStream().read(buffer, 0, size - totalRead);
}
totalRead += read;
fileStream.write(buffer, 0, read);
fileStream.flush();
if (System.currentTimeMillis() > nextPrint) {
nextPrint += 1000;
int speed = (int) (totalRead / (System.currentTimeMillis() - startTime));
double procent = ((double)totalRead / size) * 100;
gui.setStatus("Reciving: " + filename + " at " + speed + " kb/s, " + procent + "% complete");
}
}
gui.setStatus("Reciving: " + filename + " complete.");
fileStream.close();
FileOutputStream.close在接收大文件时花了很长时间,为什么?正如你所看到的那样,我正在冲洗每个收到的大块的小溪..
答案 0 :(得分:3)
根据操作系统的不同,flush()
不会强制将数据写入操作系统。在FileOutputStream的情况下,write()将所有数据传递给OS,因此flush()不执行任何操作。其中close()
可以确保文件实际写入磁盘(或不依赖于操作系统)。您可以在写入数据时查看磁盘是否仍处于忙碌状态。
500 MB的文件需要30秒才意味着您正在写入17 MB / s。这听起来像一个非常慢的磁盘或网络共享/驱动器中的文件。
你可以试试这个
File file = File.createTempFile("deleteme", "dat"); // put your file here.
FileOutputStream fos = new FileOutputStream(file);
long start = System.nanoTime();
byte[] bytes = new byte[32 * 1024];
for (long l = 0; l < 500 * 1000 * 1000; l += bytes.length)
fos.write(bytes);
long mid = System.nanoTime();
System.out.printf("Took %.3f seconds to write %,d bytes%n", (mid - start) / 1e9, file.length());
fos.close();
long end = System.nanoTime();
System.out.printf("Took %.3f seconds to close%n", (end - mid) / 1e9);
打印
Took 0.116 seconds to write 500,006,912 bytes
Took 0.002 seconds to close
从速度上可以看出,即使在收盘时,它也不会写入数据。即驱动器不是那么快。
答案 1 :(得分:1)
我在使用filestream时也看到了同样的情况。我发现如果您将文件作为readwrite打开,它会缓存所有内容,直到您关闭或处理后才会写入。 Flush没写。但是,如果您的写入扩展了文件的大小,它将自动刷新。
打开,只需在每次写入时自动刷新。