J'ai un observateur de fichier qui saisit le contenu d'un fichier en croissance encodé avec utf-16LE. Le premier bit de données qui y est écrit a la BOM disponible - je l'utilisais pour identifier l'encodage par rapport à UTF-8 (dont la plupart des fichiers entrants sont encodés). J'attrape la nomenclature et ré-encoder en UTF-8 afin que mon analyseur ne panique pas. Le problème est que, comme il s'agit d'un fichier en pleine croissance, toutes les données ne contiennent pas la nomenclature.Comment puis-je identifier différents encodages sans utiliser de nomenclature?
Voici ma question - sans préfixer la nomenclature octets à chaque ensemble de données dont je dispose (parce que je ne dispose pas de contrôle sur la source) puis je peux chercher des octets nuls qui sont inhérents au format UTF-16 \ 000, puis l'utiliser comme identifiant au lieu de la nomenclature? Cela me causera-t-il des maux de tête sur la route?
Mon architecture implique une application Web ruby enregistrant les données reçues dans un fichier temporaire lorsque mon analyseur écrit en java le récupère.
Écrire maintenant mon identification/code réencodage ressemble à ceci:
// 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();
}
MISE À JOUR
Je veux soutenir des choses comme euros, em-tirets et autres caractères en tant que tels. Je modifié le code ci-dessus pour ressembler à ceci et il semble passer tous mes tests pour ces personnages:
// 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();
}
Que pensez-vous tous?
Je ne comprends pas le problème (vous faites référence dans le premier paragraphe). Bien sûr, tous les fragments n'auront pas la BOM - mais sûrement le début du fichier. Donc, pour chaque fichier, rappelez-vous si vous avez vu la nomenclature, et si oui, traitez-la en UTF-16. –
Vous n'avez sûrement pas d'encodage mixte dans un seul fichier? –
Je n'ai pas le contrôle du fichier qui est en croissance - c'est pourquoi je ne peux pas simplement rembobiner le fichier. Je n'ai pas de codage mixte dans le même fichier - mais j'ai des codages mixtes qui traversent un réseau vers un analyseur qui accepte les codages mixtes. – eyberg