当前位置: 首页 > 面试题库 >

如何从Java中的XML文件中删除BOM

韩明德
2023-03-14
问题内容

我需要有关从UTF-8文件删除BOM并创建其余xml文件的副本的方法的建议。


问题答案:

有因为在UTF-8文件中的BOM的工具断裂是一个 非常
以我的经验平常的事。我不知道为什么会有这么多的否决票(但是这给了我机会去尝试赢得足够的选票来赢得特殊的SO徽章;)

更严重的是:UTF-8 BOM通常没有太大意义,
在规格上完全有效(尽管不建议使用)。现在的问题是,很多人不知道BOM在UTF-8中是有效的,因此编写了损坏的工具/ API,无法正确处理这些文件。

现在,您可能遇到两个不同的问题:您可能想从Java处理文件,或者需要使用Java以编程方式创建/修复其他(损坏的)工具所需的文件。

我曾在一个咨询工作中遇到过这样的情况:服务台将继续从用户那里收到消息,这些消息在某些文本编辑器上出现问题,这些文本编辑器会弄乱Java生成的完全有效的UTF-8文件。因此,我必须通过确保从我们正在处理的每个UTF-8文件中删除BOM来解决该问题。

我要从文件中删除BOM表,可以创建一个新文件并跳过前三个字节。例如:

... $  file  /tmp/src.txt 
/tmp/src.txt: UTF-8 Unicode (with BOM) English text

... $  ls -l  /tmp/src.txt 
-rw-rw-r-- 1 tact tact 1733 2012-03-16 14:29 /tmp/src.txt

... $  hexdump  -C  /tmp/src.txt | head -n 1
00000000  ef bb bf 50 6f 6b 65 ...

如您所见,文件以“ ef bb bf”开头,这是(完全有效的)UTF-8 BOM。

这是一种方法,它通过跳过前三个字节来获取文件并进行复制:

 public static void workAroundbrokenToolsAndAPIs(File sourceFile, File destFile) throws IOException {
    if(!destFile.exists()) {
        destFile.createNewFile();
    }

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(sourceFile).getChannel();
        source.position(3);
        destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom( source, 0, source.size() - 3 );
    }
    finally {
        if(source != null) {
            source.close();
        }
        if(destination != null) {
            destination.close();
        }
    }
}

请注意,它是“原始的”:通常,在调用此代码或“可能会发生错误的思维” [TM]之前,通常需要先确保您具有BOM。

您可以随后查看您的文件:

... $  file  /tmp/dst.txt 
/tmp/dst.txt: UTF-8 Unicode English text

... $  ls -l  /tmp/dst.txt 
-rw-rw-r-- 1 tact tact 1730 2012-03-16 14:41 /tmp/dst.txt

... $  hexdump -C /tmp/dst.txt
00000000  50 6f 6b 65 ...

BOM消失了…

现在,如果您只想透明地删除损坏的Java API的BOM,则可以使用此处描述的 pushbackInputStream

private static InputStream checkForUtf8BOMAndDiscardIfAny(InputStream inputStream) throws IOException {
    PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3);
    byte[] bom = new byte[3];
    if (pushbackInputStream.read(bom) != -1) {
        if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) {
            pushbackInputStream.unread(bom);
        }
    }
    return pushbackInputStream; }

请注意,此工程,但必须绝对 不是 解决更严重的问题,你可以有其他工具在工作链不与具有BOM UTF-8的文件正常工作。

这是指向更完整答案的问题的链接,还涵盖其他编码:

字节顺序标记会破坏Java中的文件读取



 类似资料:
  • 问题内容: 我已经从Excel数据库中生成了一个xml文件,它自动包含一个名为“ ” 的元素。为了使新文件符合我的需求,我想使用java删除此元素。这是xml内容: 我编写了一个代码来读取(使用缓冲的读取器)并将内容写入新文件中,并在以下情况下使用该条件: 但这不起作用 问题答案: 我个人建议使用适当的XML解析器(如Java DOM)来检查和删除您的节点,而不是将XML作为原始对象处理(糟糕)。

  • 我有一个带有声明的XML文件,需要使用XSLT将其删除,用于我使用的样式表版本=“2.0” 我拥有的xml文件(输入) 我需要的输出

  • 问题内容: 简而言之; 我在XML文件中生成了许多空行,并且我正在寻找一种删除它们的方法,以作为倾斜文件的一种方法。我怎样才能做到这一点 ? 详细说明;我目前有这个XML文件: 我使用此Java代码删除所有标签,并添加新标签: 在多次执行此方法后,我得到了一个XML文件,其结果正确,但是在“ paths”标记之后和第一个“ path”标记之前有许多空行,如下所示: 有人知道该如何解决吗? ----

  • 简言之我在XML文件中生成了许多空行,我正在寻找一种方法来删除它们,作为学习文件的一种方式。我该怎么做? 详细说明;我当前有以下XML文件: 我使用此Java代码删除所有标记,并添加新标记: 多次执行此方法后,我得到了一个结果正确的XML文件,但在“paths”标记之后和第一个“path”标记之前有许多空行,如下所示: 有人知道怎么解决吗? ----------------------------

  • 这是我的XML文件 我只想从xml中删除第二个选项 我的java代码从我的选项元素中删除所有选项。使用

  • 问题内容: 如何以一种在Windows和Linux上都可以使用的方式替换Java字符串中的所有换行符(即,没有特定于操作系统的回车/换行/换行等问题)? 我试过了(注意readFileAsString是一个将文本文件读入String的函数): 但这似乎不起作用。 如何才能做到这一点? 问题答案: 你需要text将结果设置为: 这是必需的,因为字符串是不可变的-调用不会更改原始字符串,它会返回已更改