У меня есть средство просмотра файлов, которое получает содержимое из растущего файла, кодированного с помощью utf-16LE. У первого бита данных, записанных в него, есть доступная спецификация - я использовал это для идентификации кодировки по UTF-8 (в которую МОЖЕТ большинство моих входящих файлов, закодированы). Я ловлю BOM и перекодирую в UTF-8, чтобы мой парсер не волновался. Проблема в том, что, поскольку это растущий файл, не каждый бит данных содержит спецификацию.
Вот мой вопрос - не добавляя байты спецификации к каждому набору данных (, поскольку у меня нет контроля над источником ), я могу просто искать нулевые байты, которые присущи UTF-16 \ 000, а затем использовать это как мой идентификатор вместо спецификации? Это вызовет у меня головную боль в будущем?
Моя архитектура включает в себя веб-приложение ruby, регистрирующее полученные данные во временном файле, когда мой анализатор, написанный на 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();
}
Что вы все думаете?