我有一个简单的 servlet 类将 CSV 文件返回给客户端(浏览器)。当我尝试将字符串写入流时。最初我遵循示例 A),但我注意到附加了预期数据的子集。
假设我希望在 csv 文件中捕获确切的 100 条记录。每条记录代表“名字/姓氏/年龄”。在示例 A) 中,我得到了 120。前 100 条记录是正确的,但在本例中附加了 100 条记录的子集 20 条(重复项)。
示例 A)
public void returnCSV(HttpServletResponse resp, String data) {
ServletOutputStream out = resp.getOutputStream();
InputStream in = new ByteArrayInputStream(data.getBytes("UTF-8"));
byte[] bytes = new byte[4096];
while (in.read(bytes,0,4096) != -1) {
out.write(bytes,0,4096);
}
in.close();
out.flush();
out.close();
}
阅读更多有关将字符串转换为流的线程后。我决定遵循示例 B),它生成了正确的输出 100 条记录。但我不明白为什么第一个示例 A) 会添加重复数据。
示例 B)
public void returnCSV(HttpServletResponse resp, String data) {
ServletOutputStream out = resp.getOutputStream();
out.write(data.getBytes("UTF-8"));
out.flush();
out.close();
}
最佳答案
看看这个循环:
while (in.read(bytes,0,4096) != -1) {
out.write(bytes,0,4096);
}
无论 read
读取多少数据,您始终会写出 4096 个字节。您只想复制已读取的相同数量的数据,例如
int bytesRead;
while ((bytesRead = in.read(bytes)) != -1) {
out.write(bytes, 0, bytesRead);
}
请注意,有很多第三方库都有从输入流复制到输出流的代码 - 并且您应该使用 try-with-resources 语句来关闭流。
此外,您应该调用 ServletResponse.getWriter
,而不是调用 getOutputStream
,可能在调用 ServletResponse.setCharacterEncoding
以确保它使用 UTF-8 之后。然后你可以调用:
writer.write(data);
Writer 旨在写入文本数据;输出流设计用于写入二进制数据。您可以使用 OutputStreamWriter
在流之上创建一个编写器,但由于 servlet API 会为您完成此操作,因此您不妨让它...
关于java - 在java中将字符串写入输出流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32384787/