关于堆栈溢出问题,据说可以使用InputStream
提供的mark()
和reset()
或使用PushbackInputStream
多次读取InputStream
。
在所有这些情况的内容都存储在字节数组中(即;文件的原始内容存储在主存储器中)并多次重复使用。
当文件大小超过内存大小时会发生什么情况?我认为这可能会为OutOfMemoryException
铺平道路。
有没有更好的方法可以在不在本地存储流内容的情况下多次读取流内容(即在主内存中)?
请帮助我知道这一点。提前谢谢。
这取决于流的来源。
如果是本地文件,您可以根据需要多次重新打开和重新读取流。
如果它是由进程、远程服务等动态生成的,则可能无法自由地重新生成它。在这种情况下,您需要将其存储在内存中或一些更持久(且速度较慢)的存储中,例如文件系统或存储服务。
也许类比会有所帮助。假设你的朋友正在和你长篇大论。你仔细听而不打断,但是当他们完成时,你意识到你没有理解他们在开头说的话,并想复习那部分。
在这一点上,有几种可能性。
也许你的朋友实际上是在大声朗读一本书。你可以简单地重新阅读这本书。
或者,也许你必须有远见才能记录他们的独白。您可以重播录音。
但是,由于您和您的朋友都没有完美和无限的回忆,因此仅凭记忆逐字重复十分钟前所说的话不是一种选择。
InputStream
就像你的朋友在说话。你们俩的记忆力都不够好,无法逐字逐句地准确记住所说的内容。同样,生成数据流的进程和程序都没有足够的 RAM 来逐字节存储流。为了扩展,您的程序必须依靠其"短期内存"(RAM),在任何给定时间仅处理整个流的一小部分,并在遇到重要点时"记笔记"(写入持久存储)。
如果流的源是本地文件,那么就像你的朋友在读书一样。你们中的任何一个都可以轻松地重新阅读该内容。
如果您将流复制到某个持久存储,就像录制朋友的语音一样。您可以根据需要随时重播它。
考虑这样一种情况:浏览器正在上传一个大文件,但服务器繁忙,并且在一段时间内无法读取该流。在延迟期间,数据存储在哪里?
由于接收方不能总是立即响应输入,因此TCP和许多其他协议会分配一个小缓冲区来存储来自发送方的一些数据。但是,他们也有一种方法可以告诉发送者等待,他们发送数据的速度太快了——流量控制。回到这个类比,这就像告诉你的朋友在你赶上笔记的时候停顿一下。
当浏览器上传文件时,首先,缓冲区将被填充。但是,如果服务器无法跟上,浏览器将被指示暂停其上传,直到缓冲区中有更多空间。(这通常发生在操作系统和 TCP 级别;客户端和服务器应用程序不直接管理这一点。上传速度取决于浏览器从磁盘读取文件的速度、网络链接的速度以及服务器处理上传数据的速度。即使是快速的网络和客户端也会受到该链中薄弱环节的限制。