J'écris une application Web dans Google App Engine. Il permet aux gens de modifier essentiellement le code html qui est stocké sous forme de .html
fichier dans le blobstore.
J'utilise fetchData pour renvoyer un byte[]
de tous les caractères du fichier. J'essaye d'imprimer dans un html pour que l'utilisateur modifie le code html. Tout fonctionne très bien!
Voici mon seul problème maintenant:
Le tableau d'octets rencontre des problèmes lors de la conversion en chaîne. Des citations intelligentes et quelques personnages ont l'air géniaux. (symboles? ou japonais, etc.) Plus précisément, ce sont plusieurs octets que je vois qui ont des valeurs négatives qui causent le problème.
Les guillemets intelligents reviennent au fur -108
et à mesure -109
dans le tableau d'octets. Pourquoi cela et comment puis-je décoder les octets négatifs pour afficher le codage de caractères correct?
InputStream
, puis j'y vaisbyte[]
. Maintenant, quand j'essaie de convertir lebyte[]
en String (je dois utiliser le corps de réponse pour les attaques), j'obtiens des personnages vraiment amusants pleins de guillemets et de points d'interrogation intelligents et autres. Je crois problème vôtre est le même que le mien que nous avons tous deux traitonshtml
dansbyte[]
. Pouvez-vous s'il vous plaît des conseils?String str=new String(buffer, "Cp1252");
mais aucune aide.Réponses:
Le tableau d'octets contient des caractères dans un encodage spécial (que vous devez savoir). La façon de le convertir en chaîne est:
String decoded = new String(bytes, "UTF-8"); // example for one encoding type
Au fait - les octets bruts peuvent apparaître sous forme de décimales négatives simplement parce que le type de données java
byte
est signé, il couvre la plage de -128 à 127.-109 = 0x93: Control Code "Set Transmit State"
La valeur (-109) est un caractère de contrôle non imprimable dans UNICODE. Donc UTF-8 n'est pas le bon encodage pour ce flux de caractères.
0x93
dans "Windows-1252" est le "guillemet intelligent" que vous recherchez, donc le nom Java de cet encodage est "Cp1252". La ligne suivante fournit un code de test:System.out.println(new String(new byte[]{-109}, "Cp1252"));
la source
byte
type de données de Java est signé. Les valeurs «négatives» ne sont que des octets avec le jeu d'octets le plus significatif. Il explique également quel est le jeu de caractères le plus probable que vous devriez utiliser - Windows-1252. Vous devez savoir quel jeu de caractères utiliser à partir du contexte ou de la convention, sans avoir à deviner.Java 7 et supérieur
Vous pouvez également transmettre l'encodage souhaité au
String
constructeur en tant queCharset
constante à partir de StandardCharsets . Cela peut être plus sûr que de passer l'encodage en tant queString
, comme suggéré dans les autres réponses.Par exemple, pour le codage UTF-8
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
la source
Vous pouvez essayer ceci.
String s = new String(bytearray);
la source
public class Main { /** * Example method for converting a byte to a String. */ public void convertByteToString() { byte b = 65; //Using the static toString method of the Byte class System.out.println(Byte.toString(b)); //Using simple concatenation with an empty String System.out.println(b + ""); //Creating a byte array and passing it to the String constructor System.out.println(new String(new byte[] {b})); } /** * @param args the command line arguments */ public static void main(String[] args) { new Main().convertByteToString(); } }
Production
65 65 A
la source
public static String readFile(String fn) throws IOException { File f = new File(fn); byte[] buffer = new byte[(int)f.length()]; FileInputStream is = new FileInputStream(fn); is.read(buffer); is.close(); return new String(buffer, "UTF-8"); // use desired encoding }
la source
read
lève une exception.je suggère
Arrays.toString(byte_array);
Cela dépend de votre objectif. Par exemple, je voulais enregistrer un tableau d'octets exactement comme le format que vous pouvez voir au moment du débogage qui est quelque chose comme ceci:
[1, 2, 3]
Si vous voulez enregistrer exactement la même valeur sans convertir les octets au format de caractère, faitesArrays.toString (byte_array)
ceci. Mais si vous souhaitez enregistrer des caractères au lieu d'octets, vous devez utiliserString s = new String(byte_array)
. Dans ce cas,s
est égal à l'équivalent du[1, 2, 3]
format du caractère.la source
La réponse précédente d'Andreas_D est bonne. Je vais juste ajouter que partout où vous affichez la sortie, il y aura une police et un encodage de caractères et il se peut que certains caractères ne soient pas pris en charge.
Pour déterminer si c'est Java ou votre affichage qui pose problème, procédez comme suit:
for(int i=0;i<str.length();i++) { char ch = str.charAt(i); System.out.println(i+" : "+ch+" "+Integer.toHexString(ch)+((ch=='\ufffd') ? " Unknown character" : "")); }
Java aura mappé tous les caractères qu'il ne peut pas comprendre à 0xfffd le caractère officiel des caractères inconnus. Si vous voyez un '?' dans la sortie, mais il n'est pas mappé à 0xfffd, c'est votre police d'affichage ou votre encodage qui est le problème, pas Java.
la source