【问题标题】:writing string to outputstream in java在java中将字符串写入输出流
【发布时间】:2015-11-29 19:53:42
【问题描述】:

我有一个简单的 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();
 }

【问题讨论】:

    标签: java string stream


    【解决方案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-with-resources 语句来关闭流。

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

    writer.write(data);
    

    编写器旨在写入文本数据;输出流旨在写入二进制数据。您可以使用OutputStreamWriter 在流之上创建写入器,但由于 servlet API 会为您完成此操作,您不妨让它...

    【讨论】:

    • resp.setCharacterEncoding("UTF-8"); resp.getWriter().write(data);工作得很好!谢谢!
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2013-04-03
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多