Je dois convertir un tableau d'octets en chaîne dans Android, mais mon tableau d'octets contient des valeurs négatives.
Si je convertis à nouveau cette chaîne en tableau d'octets, les valeurs que j'obtiens sont différentes des valeurs du tableau d'octets d'origine.
Que puis-je faire pour obtenir une conversion appropriée? Le code que j'utilise pour effectuer la conversion est le suivant:
// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);
// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++)
System.out.println("by1["+i+"] >> "+str1);
Je suis coincé dans ce problème.
byte[]
pour vos données binaires etString
pour votre texte?Réponses:
Votre tableau d'octets doit avoir un certain encodage. Le codage ne peut pas être ASCII si vous avez des valeurs négatives. Une fois que vous avez compris cela, vous pouvez convertir un ensemble d'octets en une chaîne en utilisant:
Il y a un tas de codages que vous pouvez utiliser, regardez la classe charset dans les javadocs Sun .
la source
UTF-8
?String str = new String(bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
La "conversion appropriée" entre
byte[]
etString
consiste à indiquer explicitement l'encodage que vous souhaitez utiliser. Si vous commencez par unbyte[]
et qu'il ne contient en fait pas de données texte, il n'y a pas de "conversion appropriée".String
s sont pour le texte,byte[]
pour les données binaires, et la seule chose vraiment sensée à faire est d' éviter de convertir entre eux à moins que vous ne deviez absolument le faire.Si vous devez vraiment utiliser un
String
pour contenir des données binaires, le moyen le plus sûr est d'utiliser le codage Base64 .la source
Le problème racine est (je pense) que vous utilisez involontairement un jeu de caractères pour lequel:
dans certains cas. UTF-8 est un exemple d'un tel jeu de caractères. Plus précisément, certaines séquences d'octets ne sont pas des codages valides en UTF-8. Si le décodeur UTF-8 rencontre l'une de ces séquences, il est susceptible de supprimer les octets incriminés ou de les décoder en tant que point de code Unicode pour "aucun caractère de ce type". Naturellement, lorsque vous essayez ensuite de coder les caractères en octets, le résultat sera différent.
La solution est:
String.toByteArray
méthode avec un jeu de caractères explicite.la source
Nous avons juste besoin d'en construire un nouveau
String
avec le tableau: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/Les octets de la chaîne résultante diffèrent selon le jeu de caractères que vous utilisez. nouvelle chaîne (octets) et nouvelle chaîne (octets, Charset.forName ("utf-8")) et nouvelle chaîne (octets, Charset.forName ("utf-16")) auront tous des tableaux d'octets différents lorsque vous appelez String # getBytes () (selon le jeu de caractères par défaut)
la source
new String(bytes)
etnew String(bytes, Charset.forName("utf-8"))
etnew String(bytes, Charset.forName("utf-16"))
auront tous des tableaux d'octets différents lorsque vous appelezString#getBytes()
(selon le jeu de caractères par défaut)char
s (et donc le texte affiché) du résultatString
diffère lors du décodagebytes
différemment. La conversion en octets en utilisant le codage par défaut (utilisezString#getBytes("charset")
pour spécifier le contraire) sera nécessairement différente car elle convertit des entrées différentes. Les chaînes ne stockent pas les éléments dontbyte[]
elles sont issues, elleschar
n'ont pas d'encodage etString
ne les stockent pas autrement.Utiliser
new String(byOriginal)
et reconvertir enbyte[]
utilisantgetBytes()
ne garantit pas deuxbyte[]
avec des valeurs égales. Cela est dû à un appel versStringCoding.encode(..)
lequel va coder leString
toCharset.defaultCharset()
. Pendant cet encodage, l'encodeur peut choisir de remplacer les caractères inconnus et d'effectuer d'autres modifications. Par conséquent, l'utilisationString.getBytes()
peut ne pas retourner un tableau égal à celui que vous avez initialement transmis au constructeur.la source
Pourquoi était le problème: Comme quelqu'un l'a déjà spécifié: Si vous commencez par un octet [] et qu'il ne contient en fait pas de données texte, il n'y a pas de "conversion appropriée". Les chaînes sont pour le texte, l'octet [] est pour les données binaires, et la seule chose vraiment sensée à faire est d'éviter de convertir entre elles à moins que vous ne deviez absolument le faire.
J'observais ce problème lorsque j'essayais de créer l'octet [] à partir d'un fichier pdf, puis de le convertir en chaîne, puis de prendre la chaîne en entrée et de la reconvertir en fichier.
Assurez-vous donc que votre logique d'encodage et de décodage est la même que moi. J'ai explicitement codé l'octet [] en Base64 et l'ai décodé pour recréer le fichier.
Cas d' utilisation: En raison de certaines limitations je tentais à envoyer
byte[]
dansrequest(POST)
et le processus se présente comme suit:Fichier PDF >> Base64.encodeBase64 (octet []) >> Chaîne >> Envoyer une demande (POST) >> recevoir une chaîne >> Base64.decodeBase64 (octet []) >> créer un binaire
Essayez ceci et cela a fonctionné pour moi ..
la source
Cela fonctionne bien pour moi:
Conversion d'une chaîne en octet []:
Conversion de l'octet [] en chaîne:
la source
la source
J'ai remarqué quelque chose qui ne figure dans aucune des réponses. Vous pouvez convertir chacun des octets du tableau d'octets en caractères et les placer dans un tableau de caractères. Ensuite, la chaîne est
où cbuf est le tableau char. Pour reconvertir, parcourez la chaîne en convertissant chacun des caractères en octets à placer dans un tableau d'octets, et ce tableau d'octets sera le même que le premier.la source
javax.xml.bind.DatatypeConverter
devrait le faire:la source
Voici quelques méthodes qui convertissent un tableau d'octets en chaîne. Je les ai testés, ils fonctionnent bien.
la source
Même si
est correct, il lance un
UnsupportedEncodingException
qui vous oblige à faire face à une exception vérifiée. Vous pouvez utiliser comme alternative un autre constructeur depuis Java 1.6 pour convertir un tableau d'octets enString
:Celui-ci ne lève aucune exception.
La reconversion doit également être effectuée avec
StandardCharsets.UTF_8
:Encore une fois, vous évitez d'avoir à traiter les exceptions vérifiées.
la source
J'ai réussi à convertir le tableau d'octets en chaîne avec cette méthode:
la source
Bien que l'encodage base64 soit sûr et que l'on puisse dire «la bonne réponse», je suis arrivé ici à la recherche d'un moyen de convertir un tableau d'octets Java vers / à partir d'une chaîne Java telle quelle. Autrement dit, où chaque membre du tableau d'octets reste intact dans son homologue String, sans espace supplémentaire requis pour l'encodage / transport.
Cette réponse décrivant des encodages transparents 8 bits m'a été très utile. J'ai utilisé
ISO-8859-1
sur des téraoctets de données binaires pour convertir avec succès (chaîne binaire <->) sans les exigences d'espace gonflées nécessaires pour un encodage base64, donc est sans danger pour mon cas d'utilisation - YMMV.Cela a également été utile pour expliquer quand / si vous devriez expérimenter.
la source
la source
Voici le code de travail.
la source
Essayez de spécifier un jeu de caractères 8 bits dans les deux conversions. ISO-8859-1 par exemple.
la source
Lisez les octets de l'
String
utilisationByteArrayInputStream
et encapsulez-le avecBufferedReader
lequel est Char Stream au lieu de Byte Stream qui convertit les données d'octets en chaîne.La sortie est:
la source
Vous pouvez utiliser simple for loop pour la conversion:
la source
la source
Une chaîne est une collection de caractères (16 bits non signés). Donc, si vous allez convertir des nombres négatifs en une chaîne, ils seront perdus lors de la traduction.
la source
la source
Utilisez Base64 et résolvez votre problème, c'est trop facile à utiliser. http://iharder.sourceforge.net/current/java/base64/
la source