У меня есть наблюдатель файлов, который захватывает контент из растущего файла, закодированного с помощью utf-16LE. Первый бит данных, записанных на него, имеет доступную спецификацию - я использовал это, чтобы идентифицировать кодировку UTF-8 (какая МОСТ из моих файлов поступает в кодировку). Я ломаю спецификацию и перекодирую в UTF-8, поэтому мой парсер не волнуется. Проблема в том, что, поскольку это растущий файл, у каждого бита данных есть спецификация.Как определить различные кодировки без использования спецификации?
Вот мой вопрос - без добавления префикса BOM байт для каждого набора данных у меня есть (, потому что у меня нет контроля над источником) могу я могу просто посмотреть на нулевые байты, которые присущи UTF-16 \ 000, а затем использовать это как мой идентификатор вместо спецификации? Это вызовет у меня головные боли по дороге?
В моей архитектуре используется рубиновое веб-приложение, регистрирующее полученные данные во временном файле, когда мой парсер, написанный в java, забирает его.
Написать теперь мой идентификационный код/перекодирования выглядит следующим образом:
// guess encoding if utf-16 then
// convert to UTF-8 first
try {
FileInputStream fis = new FileInputStream(args[args.length-1]);
byte[] contents = new byte[fis.available()];
fis.read(contents, 0, contents.length);
if ((contents[0] == (byte)0xFF) && (contents[1] == (byte)0xFE)) {
String asString = new String(contents, "UTF-16");
byte[] newBytes = asString.getBytes("UTF8");
FileOutputStream fos = new FileOutputStream(args[args.length-1]);
fos.write(newBytes);
fos.close();
}
fis.close();
} catch(Exception e) {
e.printStackTrace();
}
UPDATE
Я хочу поддержать такие вещи, как евро, эм-тир, и другие символы как таковые. Я изменил код выше, чтобы посмотреть, как это и это, кажется, передать все мои тесты для этих персонажей:
// guess encoding if utf-16 then
// convert to UTF-8 first
try {
FileInputStream fis = new FileInputStream(args[args.length-1]);
byte[] contents = new byte[fis.available()];
fis.read(contents, 0, contents.length);
byte[] real = null;
int found = 0;
// if found a BOM then skip out of here... we just need to convert it
if ((contents[0] == (byte)0xFF) && (contents[1] == (byte)0xFE)) {
found = 3;
real = contents;
// no BOM detected but still could be UTF-16
} else {
for(int cnt=0; cnt<10; cnt++) {
if(contents[cnt] == (byte)0x00) { found++; };
real = new byte[contents.length+2];
real[0] = (byte)0xFF;
real[1] = (byte)0xFE;
// tack on BOM and copy over new array
for(int ib=2; ib < real.length; ib++) {
real[ib] = contents[ib-2];
}
}
}
if(found >= 2) {
String asString = new String(real, "UTF-16");
byte[] newBytes = asString.getBytes("UTF8");
FileOutputStream fos = new FileOutputStream(args[args.length-1]);
fos.write(newBytes);
fos.close();
}
fis.close();
} catch(Exception e) {
e.printStackTrace();
}
Что вы думаете?
Я не понимаю проблему (в первом абзаце вы ссылаетесь). Конечно, не каждый фрагмент будет иметь спецификацию, но, конечно же, начало файла. Поэтому для каждого файла помните, видели ли вы спецификацию, и если да, обработайте ее как UTF-16. –
У вас нет смешанных кодировок в одном файле? –
У меня нет контроля над файлом, который растет - вот почему я не могу просто перемотать файл. У меня нет смешанных кодировок в одном файле, но у меня есть смешанные кодировки, проходящие через сеть, в парсер, который принимает смешанные кодировки. – eyberg