最近,我创建了一个界面,强制用户实现单个fromStream(OutputStream)
,其默认方法如下所示:
public default T fromFile(File file) throws IOException {
try (InputStream stream = new FileInputStream(file)) {
return fromStream(stream);
}
}
不久之后,由于直接从FileInputStream
读取单个字节,这非常昂贵(每MB数秒)。
将其包装在BufferedInputStream
中解决了我的问题,但它给我留下了一个问题:为什么FileInputStream
的价格如此昂贵。
文件通道在读取字节时不会关闭或打开,那么为什么首先需要缓冲区呢?
当您从文件中读取时,您必须一次读取一个块,因为这是硬件支持的唯一数量。如果您一次读取一个字符而不缓冲,那么假设512B块,您将读取同一个块512次以读取整个块。如果您读取并缓冲,您将访问磁盘一次,然后从内存中读取。
访问磁盘比访问内存慢几个数量级,这不是一个好主意。
如果您使用read()
方法从无缓冲流中读取字节,JVM将最终对操作系统进行重复读取系统调用以从文件中读取单个字节。(在引擎盖下,JVM可能正在调用read(addr,偏移量,计数)
,计数为1。)
进行系统调用的成本很高。至少比常规方法调用多几个数量级。这是因为在以下方面存在大量的管理费用:
相反,如果您使用缓冲流,则该流将尝试从操作系统中读取大块文件。这通常会导致系统调用数量减少数千倍。
事实上,这与文件在磁盘上的存储方式无关。的确,数据最终必须一次读取一个块,等等。然而,操作系统足够聪明,可以自己进行缓冲。它甚至可以提前读取文件的某些部分,以便在(内核)内存中为应用程序进行系统调用以读取它们做好准备。
多个单字节read()
调用极不可能导致额外的磁盘流量。唯一可行的情况是,如果您在每次读取()之间等待很长时间,
。。。操作系统会重用缓存磁盘块的空间。
我正在学习Java I/O。因此,使用缓冲流可以减少读取或写入所需的时间,因为如果使用普通的FileInputStream,每次调用读取时都会获取一个字节,但如果使用缓冲区,则会获取指定大小的数据并将其存储在内存中。所以我试着在实践中看到这一点。 我已将BufferedInputStream的缓冲区大小设置为512,8192,65536。每次需要87秒才能完成执行。所以我尝试使用FileInput
我的目标是用扩展名解析协议缓冲区文件。pb。一串在Mac上使用自制软件下载Protobuff。运行protoc--版本,并具有libprotoc 3.1.0版本。 但当我运行Python时,它会说找不到模块。我改变了主意。pb文件名到\u pb2。py并在Python脚本中导入模块。 我正在使用谷歌文档,但仍然没有任何运气。我在编译Protobuf时也遇到了问题。so文件通过Python。我只是无
问题内容: 我正在尝试从FTP服务器读取文件。该文件是一个文件。我想知道在套接字打开的情况下是否可以对此文件执行操作。我试图按照什么分两个问题,提到的阅读文件,而不写入磁盘和读取从FTP文件,而无需下载,但没有成功。 我知道如何提取下载文件上的数据/工作,但不确定是否可以即时执行。有没有一种方法可以连接到站点,在缓冲区中获取数据,还可以提取某些数据并退出? 尝试StringIO时出现错误: 我只需
两者都将找到答案996没有问题。我们使用modulos来保持合理的输出大小,使用pair来避免指数分支。 对于n=5000,C++代码输出783,但Python会抱怨 如果我们加上几行
我读到FileWriter和BufferedWriter的区别在于FileWriter直接写入文件(逐字符),white BufferedReader使用缓冲区。如果是,为什么FileWriter有缓冲区?例如,如果我创建一个FileWriter对象,如下所示: 而且,如果我在程序结束时不刷新或关闭写入器,它将不会向文件写入任何内容。这意味着它也使用缓冲区。拜托,解释一下?
两者都是序列化库,由谷歌开发人员开发。他们之间有什么大的区别吗?将使用协议缓冲区的代码转换为使用FlatBuffers需要大量工作吗?