【问题标题】:Why there is a 't' in front of column while using stream resolution return byte array outputstream? [duplicate]为什么在使用流解析返回字节数组输出流时列前面有一个“t”? [复制]
【发布时间】:2021-08-10 10:41:38
【问题描述】:

我正在使用 Spring 框架,并使用 streamresolution 返回一个 .txt 文件供用户下载。

数据的结果很好,但是每列数据前面都有一个't', 除了最后一列,每列末尾都有一个“w”。

我不明白为什么,因为数据看起来很好,而且我没有告诉程序创建这封信。

这是我的代码:

// A list of String, which are the data, it might looks like 20200810,a,b,c,100,55,.....
// the whole is a String contains comma
List<String> dataList = (List<String>) parameters.get("myData");

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamingResolution streamingResolution = null;

ObjectOutputStream oos = new ObjectOutputStream(outputStream);

oos.writeObject("\n");
for (String s : dataList) {
    oos.writeObject(s.trim());
    oos.writeUTF("\n");
}

streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));

streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);
            
String year = Integer.toString((Integer.parseInt(end.substring(0, 4));
String day = year + end.substring(4, 6);

oos.close();

return streamingResolution.setFilename(day + ".txt");

当我下载数据时,202108.txt 它可能看起来像

t ?0210810,a,b,c,100,55w

t ?0210810,d,e,f,99,60

谁能告诉我为什么前面会有一个“t” 最后是一个'w'? 以及如何解决这个问题?

非常感谢。

【问题讨论】:

  • 您正在尝试将二进制数据作为文本读取。我很惊讶它竟然如此明智。
  • 我希望它在这一次更聪明,知道我想要它是什么。 ^^

标签: java spring-mvc


【解决方案1】:

此代码使用ObjectOutputStream,用于以二进制格式写入序列化的Java 数据。它不是纯文本格式,不应以这种方式使用。额外的字符是在Java Object Serialization Specification 中定义的字节。

要编写纯文本,您可以改用java.io.PrintStream 类。例如:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream, false, StandardCharsets.UTF_8);

printStream.println();
for (String s : dataList) {
    printStream.println(s.trim());
}
printStream.flush();

StreamingResolution streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));

streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);

请注意,我还通过将 streamingResolution 局部变量声明移动到分配它的位置来简化代码。

这是对所提供代码的直接翻译,向您展示如何使用PrintStream 类,但它可能不是最好的编写方式。 StreamingResolution 类似乎是 Stripes Framework 的一部分。它旨在将大量响应流式传输到客户端。但是,此实现实际上并不流式传输响应,而是将其累积到一个字节数组中。实现这一点的更好方法是子类化 StreamingResponse 类,如 Stripe 文档中所述,直接写入响应:

return new StreamingResolution("text/plain") {
    public void stream(HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.println();
        for (String s : dataList) {
            out.println(s.trim());
        }
        out.flush();
    }
}.setFilename(day + ".txt");

【讨论】:

  • 非常感谢您的出色回答。它确实解决了我的问题,谢谢。我更改了代码,并使用了 PrintStream,程序运行良好,结果正是我想要的。谢谢。我唯一改变的是,当我使用新的PrintStream时,它说参数应该是(输出流,布尔值,字符串),所以我写了PrintStream printStream = new PrintStream(outputStream, false, UTF-8);下面的代码似乎更好,因为我已经得到了一个工作代码,我想尝试另一个。再次感谢您的回答。
  • 我的荣幸。我很高兴它有帮助!我应该提到,我使用的 PrintStream 构造函数是在 Java 10 中引入的。使用带有 String 的版本也完全可以,并且向后兼容。
  • 哦,我明白了。我已经尝试了这两个代码,并且它们工作得很好。 streamingResponse 似乎比另一个更快。感谢您的回答和出色的示例代码。 ^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-24
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
相关资源
最近更新 更多