使用FSDataOutputStream将不需要的字符从java REST-API写入HadoopDFS

使用FSDataOutputStream将不需要的字符从java REST-API写入HadoopDFS,java,special-characters,hdfs,dataoutputstream,Java,Special Characters,Hdfs,Dataoutputstream,我们构建了一个JavaREST-API来接收事件数据(比如点击购买按钮)并将数据写入HDFS。 本质上,我们为每个发送数据(JSON)的主机打开流或使用现有的流,使用时间戳、事件名称和主机名丰富数据,并将其写入(FS)DataOutputStream: 1 public synchronized void writeToFile(String filename, String hostname, String content) throws IOException { 2 FSDataOu

我们构建了一个JavaREST-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  }
首先,我们在第3行中使用了
stream.writeChars(content)
,生成如下文件:
{.m.e.s.s.a.g.e.:.h.e.l.l.o.}
查看DataOutputStream.writeChars(字符串s)的实现,您会看到向右移动8位,并为每个字符添加一个前导x00,原因我不明白

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

所以我的最后一个选择是stream.writeBytes(content)。这里一切看起来都很好:
{“message”:“hello”}
直到特殊角色进场:
{“message”:“hallöchen”}
变成了
{“message”:“hall.chen”}
。writeBytes在写入字符之前剪切字符的前导8位。我想我需要一些UTF-8功能来正确编写这些字符

所以,现在我有点迷路了。我如何解决这个问题呢?

当我读到这篇文章时:我觉得上面提到的FSDataOutputStream方法对此不起作用。 一个快速(可能是肮脏的)解决方案是:

3 byte[] contentAsBytes = content.getBytes("UTF-8");
4 for (byte singleByte : contentAsBytes) {
5   stream.writeByte(singleByte);
6 }
更干净的方法是不使用FSDataOutputStream,但我找不到替代方法。
您是否尝试过将FSDataOutputStream包装在java.io.PrintStream中并使用其打印方法。这很难做到,但请告诉我这是否适合您。

stream.write(contentAsBytes,0,contentAsBytes.length);可以替换您的for循环。