2015-09-03 47 views
1

我有一个简单的servlet类将CSV文件返回给客户端(浏览器)。当我试图写入字符串流。最初我遵循例子A),但我注意到预期数据的子集被追加。在java中将输出流写入字符串

比方说,我预计精确的100个记录将被捕获在一个csv文件中。每个记录代表“名/姓/年龄”。在例子A)中,我得到了120个。前100个记录是正确的,但是在这个例子中是20个(重复)的100个子集被追加。

例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(); 
} 

回答

1

看这个循环:

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-与资源语句仍要关闭流。

此外,您应该调用ServletResponse.getWriter,而不是调用getOutputStream,可能在调用ServletResponse.setCharacterEncoding后确保其使用UTF-8。然后你可以拨打电话:

writer.write(data); 

作家被设计来写文本数据;输出流被设计为写入二进制数据。您可以使用OutputStreamWriter在流的顶部创建一个编写器,但由于servlet API将为您执行该操作,因此您可能会放过它...

+0

谢谢您的解释和建议。 – DaeYoung

+0

resp.setCharacterEncoding(“UTF-8”); 。resp.getWriter()写(数据);非常棒!谢谢! – DaeYoung