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

标签 java special-characters hdfs dataoutputstream

我们构建了一个 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  }

首先,我们在第 3 行使用了 stream.writeChars(content),生成的文件如下: .{".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 中的字节数,然后发送字符串本身。所以 .W 表示事件数据中的字节数,当改变事件数据的长度时证明文件中显示不同的前导字符。

所以我的最后一招是,stream.writeBytes(content)。这里一切看起来都很好: {"message":"hello"} 直到出现特殊字符: {"message":"hallöchen"} 变成了 {"message":"hall.chen"}。 writeBytes 在写入之前删除字符的前 8 位。我想我需要一些 UTF-8 功能才能正确写入这些字符。

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

最佳答案

当我读到这篇文章时:Why does DataOutputStream.writeUTF() add additional 2 bytes at the beginning?我觉得上面提到的 FSDataOutputStream 方法对此不起作用。 一个快速(也可能是肮脏的)解决方案是这样的:

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

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

关于java - 使用 FSDataOutputStream 从 Java REST-API 写入 HadoopDFS 的不需要的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19687576/

相关文章:

java - 查找二维数组中的最大元素

Java,在多线程环境下通过散列统一划分传入的工作

linux - 修改 hadoop 作业中的 LD_LIBRARY_PATH JAVA_LIBRARY 和 CLASSPATH

hadoop - hdfs 上具有 3 个复制的文件将存储在 3 个主机上?

java - 如何将不同的变量传递给 JUnit5 中的 beforeEach Hook

Java Jackson 默认类型映射

使用特殊字符在 solr 中搜索

java - Java 中的 Unicode 符号(箭头)

javascript - 替换直 Angular 括号

hadoop - 有没有办法为 HDFS 中的某些目录设置 TTL?