Comment décoder les données UTF-16 en Perl, quand je ne sais pas l'ordre des octets?
Si j'ouvre un fichier ( et de spécifier un encodage directement ) :
open(my $file,"<:encoding(UTF-16)","some.file") || die "error $!\n";
while(<$file>) {
print "$_\n";
}
close($file);
Je peux lire le contenu du fichier joliment. Cependant, si je fais:
use Encode;
open(my $file,"some.file") || die "error $!\n";
while(<$file>) {
print decode("UTF-16",$_);
}
close($file);
J'obtiens l'erreur suivante:
UTF-16:Unrecognised BOM d at F:/Perl/lib/Encode.pm line 174
Comment puis-je le faire fonctionner avec decode
?
EDIT: voici le premier de plusieurs octets:
FF FE 3C 00 68 00 74 00
Pouvez-vous nous montrer une image de la première de plusieurs octets du fichier?
Ah, si vous avez une NOMENCLATURE.
Ah, si vous avez une NOMENCLATURE.
OriginalL'auteur Geo | 2010-05-22
Vous devez vous connecter pour publier un commentaire.
Si vous spécifiez simplement "UTF-16", Perl va regarder pour la marque d'ordre d'octet (BOM) pour comprendre comment l'analyser. Si il n'existe pas de NOMENCLATURE, il va exploser. Dans ce cas, vous avez à dire à Coder laquelle l'ordre des octets que vous avez en spécifiant "UTF-16LE" pour "little endian" ou "UTF-16BE" pour big-endian.
Il y a quelque chose d'autre à faire avec votre situation de bien, mais c'est difficile à dire sans voir les données que vous avez dans le fichier. Je reçois la même erreur avec les deux extraits. Si je n'ai pas de NOMENCLATURE et je ne spécifiez pas d'ordre des octets, mon Perl se plaint de toute façon. Qui Perl utilisez-vous et quelle plate-forme avez-vous? Est-ce que votre plate-forme ont le natif de stockage de votre fichier? Je pense que le comportement que je vois est correct d'après les docs.
Aussi, vous ne pouvez pas tout simplement lire une ligne dans un inconnu de codage (ce que Perl est par défaut), puis les expédier hors de
decode
. Vous risquez de vous retrouver au milieu d'un multi-séquence d'octets. Vous devez utiliserEncode::FB_QUIET
pour enregistrer la partie de la mémoire tampon que vous ne pouviez pas de décoder et d'ajouter que pour le prochain bloc de données:Vous pouvez décoder le tout à la fois parce qu'il voit la NOMENCLATURE pour l'ensemble de la chaîne. La rupture en lignes individuelles signifie que le MOB est uniquement pour le premier morceau. Encoder ne pas faire quelque chose de spécial pour essayer de deviner qu'une chaîne est en quelque sorte lié à l'autre.
OriginalL'auteur brian d foy
Vous avez besoin de spécifier l'encodage UTF-16BE ou UTF-16LE. Voir http://perldoc.perl.org/Encode/Unicode.html#Size%2c-Endianness%2c-and-BOM
OriginalL'auteur Snake Plissken
Ce que vous essayez de faire, impossible.
Vous êtes en train de lire lignes de texte sans spécifier un encodage, de sorte que chaque octet qui contient un caractère de saut de ligne (par défaut
\x0a
) est la fin d'une ligne. Mais ce caractère de saut de ligne peut très bien être dans le milieu d'un caractère UTF-16, et dans ce cas votre ligne suivante ne peut pas être décodé.Si vos données sont en UTF-16LE, cela arrive tout le temps – retours à la ligne sont
\x0a \x00
. Si vous avez UTF16-ÊTRE, vous pourriez avoir de la chance (les retours à la ligne sont\x00 \x0a
), jusqu'à ce que vous obtenez un personnage avec\x0a
dans l'octet de poids fort.Donc, ne faites pas cela, ouvrez le fichier dans le bon encodage.
Il n'est pas impossible: voir ma réponse pour savoir comment vous devez gérer incomplète les séquences d'octets.
OriginalL'auteur mscha