我正在从 Web 服务中读取一个大的 csv,如下所示:
br = new BufferedReader(new InputStreamReader(website.openStream(), "UTF-16"));
我逐行读取并写入数据库。写入数据库是此操作的瓶颈,我想知道我是否有可能使用 web 服务“超时”,所以我得到 web 服务只是切断连接的情况,因为我没有从中读取任何内容.. .
还是 BufferedReader 只是将流缓冲到内存中,直到我从中读取?
是的,当您写入数据库时,Web 服务流可能会超时。如果数据库真的足够慢以至于这可能会超时,那么您可能需要在将文件推送到数据库之前将其复制到本地。
正如您所推测的, BufferedReader会将流的内容读入内存。read
任何对或readLine
将从缓冲区读取数据的调用,而不是从原始流中读取数据,假设数据已经在缓冲区中可用。这里的优点是数据是以较大的批次读取的,而不是在每次调用read
or时从流中请求readLine
。
如果您正在读取大量数据,您可能只会遇到您描述的超时。我在找到可靠的参考资料时遇到了一些麻烦,但我已经看到几次提到默认缓冲区大小BufferedReader
为 8192 字节 (8kb)。这意味着如果您的流正在读取超过 8kb 的数据,则缓冲区可能会填满并导致您的进程在从流中读取更多数据之前等待 DB 瓶颈。
如果您认为需要保留比这更大的缓冲区,则BufferedReader
构造函数会使用第二个参数重载,允许您以字节为单位指定缓冲区的大小。但是请记住,除非您移动足够小的数据块来缓冲整个流,否则即使使用更大的缓冲区也可能会遇到同样的问题。
br = new BufferedReader(new InputStreamReader(website.openStream(), "UTF-16"), size);
将使用字节BufferedReader
缓冲区初始化您。size
编辑:
阅读@Keith 的评论后,我认为他在这里是正确的。如果您遇到超时,较小的缓冲区将导致您更频繁地从套接字读取,希望能消除该问题。如果他发布了一个答案,你应该接受他的。
+1 为布赖恩的回答。
此外,我建议您查看我在 GitHub 上的 csv-db-tools。该csv-db-importer
模块说明了如何将大型 CSV 文件导入数据库。该代码经过优化,可以一次插入一行,并使内存中没有从大型 CSV 文件缓冲的数据。
BufferedReader 只是将块读入内部缓冲区,其默认大小未指定,但多年来一直是 4096 个字符。当您不调用它时,它不会做任何事情。
但我认为你认为的问题甚至不存在。我看不出网络服务是如何知道的。TCP 中的写超时很难实现。有些平台为此提供了 API,但 Java 不支持它们。
Web 服务很可能只是使用阻塞模式套接字,如果您的阅读速度不够快,它只会阻塞其写入。