В этой статье показано, как добавить, проверить и удалить метку порядка байтов (BOM) из файла UTF-8. Представление спецификации UTF-8 представляет собой последовательность байтов 0xEF
, 0xBB
, 0xBF
(шестнадцатеричный), в начале файла.
- 1. Добавление спецификации в файл UTF-8
- 2. Проверьте, содержит ли файл спецификацию UTF-8
- 3. Удалить спецификацию из файла UTF-8
- 4. Скопируйте файл и добавьте спецификацию
- 5. Скачать Исходный Код
- 6. Рекомендации
Дальнейшее чтение Подробнее о Спецификация и UTF-8
P.S Приведенные ниже примеры спецификаций работают только для файла UTF-8.
1. Добавление спецификации в файл UTF-8
Чтобы добавить спецификацию в файл UTF-8, мы можем напрямую записать Юникод \ufeff
или три байта 0xEF
, 0xBB
, 0xBF
в начале файла UTF-8.
Примечание Юникод \ufeff
представляет 0xEF
, 0xBB
, 0xBF
, прочитайте это .
1.1 В приведенном ниже примере напишите спецификацию в файл UTF-8 /home/mkyong/file.txt
.
package com.mkyong.io.howto; import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class AddBomToUtf8File { public static void main(String[] args) throws IOException { Path path = Paths.get("/home/mkyong/file.txt"); writeBomFile(path, "mkyong"); } private static void writeBomFile(Path path, String content) { // Java 8 default UTF-8 try (BufferedWriter bw = Files.newBufferedWriter(path)) { bw.write("\ufeff"); bw.write(content); bw.newLine(); bw.write(content); } catch (IOException e) { e.printStackTrace(); } } }
Выход
$ hexdump -C /home/mkyong/file.txt 00000000 ef bb bf 6d 6b 79 6f 6e 67 0a 6d 6b 79 6f 6e 67 |...mkyong.mkyong| 00000010 $ file /home/mkyong/file.txt file.txt: UTF-8 Unicode (with BOM) text $ cat /home/mkyong/file.txt mkyong mkyong
1.2 До Java 8, БуферизоВанный писатель
и OutputStreamWriter
примеры записи спецификации в файл UTF-8.
private static void writeBomFile(Path path, String content) { try (BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(path.toFile()) , StandardCharsets.UTF_8))) { bw.write("\ufeff"); bw.write(content); bw.newLine(); bw.write(content); } catch (IOException e) { e.printStackTrace(); } }
1.3 Печатающий автор
и OutputStreamWriter
Выходной поток//пример записи спецификации в файл UTF-8. 0xffff/| - это кодовая точка метки порядка байтов (спецификации).
private static void writeBomFile(Path path, String content) { try (PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream(path.toFile()), StandardCharsets.UTF_8))) { //pw.write("\ufeff"); pw.write(0xfeff); // alternative, codepoint pw.write(content); pw.write(System.lineSeparator()); pw.write(content); } catch (IOException e) { e.printStackTrace(); } }
1.4 В качестве альтернативы мы можем записать последовательность байтов спецификации 0xEF
, 0xBB
, и 0xBF
непосредственно в файл.
private static void writeBomFile4(Path path, String content) { try (FileOutputStream fos = new FileOutputStream(path.toFile())) { byte[] BOM = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}; fos.write(BOM); fos.write(content.getBytes(StandardCharsets.UTF_8)); fos.write(System.lineSeparator().getBytes(StandardCharsets.UTF_8)); fos.write(content.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } }
2. Проверьте, содержит ли файл спецификацию UTF-8
Приведенный ниже пример считывает первые 3 байта из файла и проверяет, содержит ли он 0xEF
, 0xBB
, 0xBF
последовательность байтов.
package com.mkyong.io.howto; import org.apache.commons.codec.binary.Hex; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class CheckBom { public static void main(String[] args) throws IOException { Path path = Paths.get("/home/mkyong/file.txt"); if(isContainBOM(path)){ System.out.println("Found BOM!"); }else{ System.out.println("No BOM."); } } private static boolean isContainBOM(Path path) throws IOException { if(Files.notExists(path)){ throw new IllegalArgumentException("Path: " + path + " does not exists!"); } boolean result = false; byte[] bom = new byte[3]; try(InputStream is = new FileInputStream(path.toFile())){ // read first 3 bytes of a file. is.read(bom); // BOM encoded as ef bb bf String content = new String(Hex.encodeHex(bom)); if ("efbbbf".equalsIgnoreCase(content)) { result = true; } } return result; } }
Выход
Found BOM!
Двоичный файл импортируйте org.apache.commons.codec.. Шестнадцатеричный;
находится в приведенной ниже commons-кодеке
библиотеке. Или мы можем использовать один из этих методов для преобразования байтов в шестнадцатеричный .
commons-codec commons-codec 1.14
3. Удалить спецификацию из файла UTF-8
Приведенный ниже пример ByteBuffer
для удаления спецификации из файла UTF-8.
P.S Некоторые анализаторы XML, JSON, CSV могут не выполнить синтаксический анализ или обработку файла, если он содержит спецификацию в файле UTF-8; Обычно перед анализом файла спецификацию удаляют или пропускают.
package com.mkyong.io.howto; import org.apache.commons.codec.binary.Hex; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class RemoveBomFromUtf8File { public static void main(String[] args) throws IOException { Path path = Paths.get("/home/mkyong/file.txt"); writeBomFile(path, "mkyong"); removeBom(path); } private static void writeBomFile(Path path, String content) { // Java 8 default UTF-8 try (BufferedWriter bw = Files.newBufferedWriter(path)) { bw.write("\ufeff"); bw.write(content); bw.newLine(); bw.write(content); } catch (IOException e) { e.printStackTrace(); } } private static boolean isContainBOM(Path path) throws IOException { if (Files.notExists(path)) { throw new IllegalArgumentException("Path: " + path + " does not exists!"); } boolean result = false; byte[] bom = new byte[3]; try (InputStream is = new FileInputStream(path.toFile())) { // read 3 bytes of a file. is.read(bom); // BOM encoded as ef bb bf String content = new String(Hex.encodeHex(bom)); if ("efbbbf".equalsIgnoreCase(content)) { result = true; } } return result; } private static void removeBom(Path path) throws IOException { if (isContainBOM(path)) { byte[] bytes = Files.readAllBytes(path); ByteBuffer bb = ByteBuffer.wrap(bytes); System.out.println("Found BOM!"); byte[] bom = new byte[3]; // get the first 3 bytes bb.get(bom, 0, bom.length); // remaining byte[] contentAfterFirst3Bytes = new byte[bytes.length - 3]; bb.get(contentAfterFirst3Bytes, 0, contentAfterFirst3Bytes.length); System.out.println("Remove the first 3 bytes, and overwrite the file!"); // override the same path Files.write(path, contentAfterFirst3Bytes); } else { System.out.println("This file doesn't contains UTF-8 BOM!"); } } }
Выход
Found BOM! Remove the first 3 bytes, and overwrite the file!
4. Скопируйте файл и добавьте спецификацию
В приведенном ниже примере скопируйте файл и добавьте спецификацию в целевой файл.
package com.mkyong.xml.sax; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class CopyAndAddBomToXmlFile { public static void main(String[] args) { Path src = Paths.get("src/main/resources/staff.xml"); Path dest = Paths.get("src/main/resources/staff-bom.xml"); writeBomFile(src, dest); } private static void writeBomFile(Path src, Path dest) { try (FileOutputStream fos = new FileOutputStream(dest.toFile())) { byte[] BOM = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}; // add BOM fos.write(BOM); // BOM + src to fos Files.copy(src, fos); } catch (IOException e) { e.printStackTrace(); } } }
5. Скачать Исходный Код
$клон git $клон git
$cd java-ввод-вывод
6. Рекомендации
- Википедия – Метка порядка байтов
- Стековый поток – В чем разница между UTF-8 и UTF-8 без спецификации?
- Java – Создание и запись файла
- Как записать в файл на Java – BufferedWriter
- Ошибка SAX – Содержимое не допускается в прологе
- Java – Как объединять и разделять байтовые массивы, байты
- Ява – Как преобразовать массивы байтов в шестнадцатеричный
- СПЕЦИФИКАЦИЯ: Глоссарий Java
Оригинал: “https://mkyong.com/java/java-how-to-add-and-remove-bom-from-utf-8-file/”