我非常了解 Java 库,所以当我意识到显然没有简单的方法可以用流做一些看似简单的事情时,我感到很惊讶。我正在尝试读取包含多部分表单数据的 HTTP 请求(大的多行标记分隔为看起来像的分隔符,例如,------WebKitFormBoundary5GlahTkFmhDfanAn--
),并且我想读取直到遇到具有给定名称的请求的一部分,然后返回该部分的 InputStream。
我可以将流读入内存并返回 a ByteArrayInputStream
,因为提交的文件不应大于 1MB。但是,我想确保如果文件大于 1MB,读取方法会引发异常,以便过大的文件不会填满 JVM 的内存并导致服务器崩溃。文件数据可能是二进制的,因此排除BufferedReader.readLine()
(它会删除换行符,可能是 、 或 中的任何一个\r
,\n
导致\r\n
数据丢失)。
所有明显的标记化解决方案,例如Scanner
,将标记读取为String
s,而不是流,这可能导致OutOfMemoryError
s 用于大文件——这正是我想要避免的。据我所知,没有任何等价物Scanner
将每个令牌作为 an 返回InputStream
而不将其读入内存。是否有我遗漏的东西,或者有什么方法可以自己创建类似的东西,只使用标准 Java 库(没有Apache Commons 等),不需要我一次读取流一个字符并自己编写所有令牌扫描代码?
附录:在发布此之前不久,我意识到我最初的问题的明显解决方案是将完整的请求正文读入内存,如果它太大则失败,然后ByteArrayInputStream
用Scanner
. 这是低效的,但它有效。但是,我仍然很想知道是否有一种方法可以将 a 标记InputStream
为子流,无需将它们读入内存,无需使用额外的库,也无需采用逐个字符的处理。