Java FileOutputStream非常慢

Java FileOutputStream非常慢,java,android,file-io,Java,Android,File Io,我正在从网络上下载数据库,大小在100KB到500KB之间。这是我的代码(删除无用代码): 我的问题是,他需要很长时间才能完成while语句。我把代码弄错了吗?这么小的文件不会花那么长时间吧?我说的是1分钟,对于总共不超过1MB的三个文件。。。提前谢谢 “慢”真的很含糊。也就是说,考虑到您要做的事情,您不应该使用BufferedInputStream,您的缓冲区也太小了 缓冲包装器用于优化小型读/写操作。由于您所做的只是尽可能快地读取大量数据,因此您应该直接从InputStream读取数据,并使

我正在从网络上下载数据库,大小在100KB到500KB之间。这是我的代码(删除无用代码):

我的问题是,他需要很长时间才能完成while语句。我把代码弄错了吗?这么小的文件不会花那么长时间吧?我说的是1分钟,对于总共不超过1MB的三个文件。。。提前谢谢

“慢”真的很含糊。也就是说,考虑到您要做的事情,您不应该使用
BufferedInputStream
,您的
缓冲区也太小了

缓冲包装器用于优化小型读/写操作。由于您所做的只是尽可能快地读取大量数据,因此您应该直接从
InputStream
读取数据,并使用一个大的缓冲区(比如64k,因为底层的本机代码可能会以该大小进行块处理)

“慢”真的很含糊。也就是说,考虑到您要做的事情,您不应该使用
BufferedInputStream
,您的
缓冲区也太小了

缓冲包装器用于优化小型读/写操作。由于您所做的只是尽可能快地读取大量数据,因此您应该直接从
InputStream
读取数据,并使用一个大的缓冲区(比如64k,因为底层的本机代码可能会以该大小进行块处理)



我在Jdk 1.7中找到了真正的解决方案,它由可靠、快速、,简单且几乎肯定会给旧的java.io解决方案蒙上一层遗憾的面纱。尽管web上仍然有大量使用in/out Streams在java中复制文件的示例,我还是热情地建议大家使用一种简单的方法:java.nio.files.copy(路径来源,路径目的地)使用可选参数替换目标,迁移元数据文件属性,甚至尝试文件的事务性移动(如果底层O.S.允许)。那真是一份好工作,等了这么久!通过将“.toPath()”附加到文件实例(例如file1.toPath(),file2.toPath()),可以轻松地从副本(filefile1,file2)转换代码。另外请注意,布尔方法是samefile(file1.toPath(),file2.toPath()),已在上述复制方法中使用,但在任何情况下都可以轻松使用。对于任何情况,都无法使用Apache(commons io)或Google(guava commons)的社区库升级到1.7仍然是建议。

我在Jdk 1.7中找到了真正的解决方案,它由可靠、快速、简单和几乎肯定会在旧的java.io解决方案上产生一层遗憾的面纱。尽管web上仍然有大量使用in/out Streams在java中复制文件的示例,但我还是热情地建议大家使用一种简单的方法:java.nio.Files.copy(路径原点,路径目标)使用可选参数替换目标,迁移元数据文件属性,甚至尝试文件的事务性移动(如果底层O.S.允许的话)。这是一项非常好的工作,等待了这么久!您可以轻松地从副本(文件1,文件2)转换代码通过将“.toPath()”附加到文件实例(例如file1.toPath(),file2.toPath()。还要注意的是,布尔方法是samefile(file1.toPath(),file2.toPath()),已在上述复制方法中使用,但在任何情况下都很容易使用。对于每种情况,都不能使用Apache社区库升级到1.7(commons io)或谷歌(guava commons)仍然是建议。

是什么让你认为问题出在
FileOutputStream
上?问题可能很容易就是下载数据的带宽。你是否使用了类似Traceview的工具来确定你在哪里花费时间?我不知道Traceview是什么。我调试了代码,这是因为while状态我还认为,数据的下载是在我的InputStream对象实例化时完成的。或者它不是在那里下载的?使用1024缓冲区是个坏主意。在智能手机中,所有媒体的块大小通常为4096字节或更大(例如SD卡)。谢谢。你的回答是对的。正是带宽让写入方法变得如此缓慢。是什么让你认为
FileOutputStream
的问题?下载数据的带宽也很容易成为问题。你是否使用过Traceview之类的工具来确定你的时间花在了哪里?我不知道hat Traceview是。我调试了代码,这是因为while语句,它真的很慢。我还认为,数据下载是在我的InputStream对象实例化时完成的。或者它不是在那里下载的?使用1024缓冲区是个坏主意。在智能手机中,所有媒体的块大小通常为4096字节或更大更大的(例如SD卡)。谢谢。你说得对。正是带宽让写入方法变得如此缓慢。我会试试。有关于Java I/O的好的在线文献吗?这让我有点困惑:)我必须用谷歌搜索一下,但这不是Java特有的。这样想吧——如果你必须把一堆水从一个地方移到另一个地方,速度会更快;使用一个16盎司的杯子或一个5加仑的桶?有了这个小缓冲,你就必须把它装满和清空很多次,这是有成本的。缓冲包装是为你知道你需要的时候准备的We’我们需要一堆水,但一次只想处理一杯水。它会预先取出水桶,让你从中装满水。当水桶空了,它会重新装满水。过去几天我一直在思考你的答案,我想:为什么很多人创建的字节数组比你在answ中提供给我的更小呃,如果速度较慢?一般来说,您只分配所需的缓冲区大小。为什么
URLConnection uConnection = downloadUrl.openConnection();
InputStream iS = uConnection.getInputStream();
BufferedInputStream bIS = new BufferedInputStream(iS);
byte[] buffer = new byte[1024];
FileOutputStream fOS = new FileOutputStream(db);
int bufferLength = 0;
while ((bufferLength = bIS.read(buffer)) > 0) {
fOS.write(buffer, 0, bufferLength);
}
fOS.close();
byte[] buffer = new byte[65536];
...
while ((bufferLength = iS.read(buffer, 0, buffer.length) > 0) {
    ...