2

我们构建了一个 java REST-API 来接收事件数据(例如单击购买按钮)并将该数据写入 HDFS。本质上,我们为正在发送数据(以 JSON 格式)或使用现有数据的每个主机打开流,使用时间戳、事件名称和主机名丰富数据,并将其写入 (FS)DataOutputStream:

1 public synchronized void writeToFile(String filename, String hostname, String content) throws IOException {
2    FSDataOutputStream stream = registry.getStream(filename, hostname);
3    stream.writeBytes(content);
4    stream.hflush();
5  }

首先,我们stream.writeChars(content)在第 3 行中使用,产生如下文件: .{.".m.e.s.s.a.g.e.".:.".h.e.l.l.o.".} 查看 DataOutputStream.writeChars(String s) 的实现,您会看到向右移动 8 位并为每个字符添加前导 x00,原因我不知道不明白。

然后我在第 3 行尝试stream.writeUTF(content),文件看起来好多了: .W{"message":"hello"} 但仍然是几个字节。查看代码, writeUTF(String s) 首先发送 s 中的字节数,然后是字符串本身。So.W表示事件数据中的字节数,证明当改变事件数据的长度时,文件中显示了不同的前导字符。

所以我最后的手段,stream.writeBytes(content)。这里一切看起来都很好: {"message":"hello"}直到特殊字符发挥作用: {"message":"hallöchen"}成为{"message":"hall.chen"}. writeBytes 在写入字符之前会剪切字符的前 8 位。我想我需要一些 UTF-8 功能来正确编写这些字符。

所以,现在我有点迷路了。我该如何解决?

4

2 回答 2

1

当我读到这个:为什么 DataOutputStream.writeUTF() 在开头添加额外的 2 个字节?我觉得提到的 FSDataOutputStream 方法不适用于此。一个快速(可能是肮脏)的解决方案是:

3 byte[] contentAsBytes = content.getBytes("UTF-8");
4 for (byte singleByte : contentAsBytes) {
5   stream.writeByte(singleByte);
6 }

更简洁的方法是不使用 FSDataOutputStream,但我找不到替代方法。任何提示仍然值得赞赏。

于 2013-10-31T10:15:48.223 回答
0

您是否尝试过将 FSDataOutputStream 包装在 java.io.PrintStream 中并使用其打印方法。这是一个很长的镜头,但让我知道这是否适合你。

于 2015-03-12T17:30:20.833 回答