Java字节数组和DataOutputStream处理

Java字节数组和DataOutputStream处理,java,Java,我们正在处理一个字节[],如下所示(该文件已发布到web服务器,此代码在Glassfish中运行),并发现一些文件的开头有一个字节顺序标记(BOM,三字节序列0xEF,0xBB,0xBF,请参见:),我们希望删除此BOM。我们如何检测和删除此代码中的BOM?谢谢 private final void serializePayloadToFile(File file, byte[] payload) throws IOException { FileOutputStream fos;

我们正在处理一个字节[],如下所示(该文件已发布到web服务器,此代码在Glassfish中运行),并发现一些文件的开头有一个字节顺序标记(BOM,三字节序列0xEF,0xBB,0xBF,请参见:),我们希望删除此BOM。我们如何检测和删除此代码中的BOM?谢谢

  private final void serializePayloadToFile(File file, byte[] payload) throws IOException {

    FileOutputStream fos;
    DataOutputStream dos;

    fos = new FileOutputStream(file, true); // true for append
    dos = new DataOutputStream(fos);

    dos.write(payload);
    dos.flush();
    dos.close();
    fos.close();

    return;
  }  
我们如何检测[…]

显然无法确定这三个字节是三个随机字节还是三个代表BOM的字节

您可以检查数组是否以0xEF、0xBB、0xBF开头,在这种情况下可以跳过它们

[…]并删除此代码中的BOM表?

这样做应该可以:

int off = payload.length >= 3
       && payload[0] == 0xEF
       && payload[1] == 0xBB
       && payload[2] == 0xBF ? 3 : 0

dos.write(payload, off, payload.length - off);

最简单的解决方案似乎是在
dos
fos
之间添加另一个
OutputStream
实现,并在将它们实际提交到
fos
之前在那里缓冲前几个字节。根据它们的值,您可能想丢弃它们,也可能不想丢弃它们。

有一个带有偏移量和长度的write()方法

public void write(byte[] b, int off, int len);

因此,测试字节顺序标记并适当地抵消(和len)。

不要忘记测试
有效负载。长度>2
有一种方法可以确保字节是BOM;如果文件使用UTF-8编码,并且以0xEF 0xBB 0xBF开头,那么这三个字节就是一个BOM。谢谢,但听起来可能有点太复杂了…?但它在比处理字节数组更复杂的情况下工作(如重定向流等):