Tableau d'octets à la Chaîne et au retour.. des problèmes avec -127
Le suivant:
scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127))).getBytes
res12: Array[Byte] = Array(1, 2, 3, -1, -2, 63)
pourquoi est--127 converti à 63? et comment puis-je le récupérer comme -127
[EDIT:] version de Java ci-dessous (pour montrer que ce n'est pas juste un "Scala problème")
c:\tmp>type Main.java
public class Main {
public static void main(String [] args) {
byte [] b = {1, 2, 3, -1, -2, -127};
byte [] c = new String(b).getBytes();
for (int i = 0; i < 6; i++){
System.out.println("b:"+b[i]+"; c:"+c[i]);
}
}
}
c:\tmp>javac Main.java
c:\tmp>java Main
b:1; c:1
b:2; c:2
b:3; c:3
b:-1; c:-1
b:-2; c:-2
b:-127; c:63
Vous devez vous connecter pour publier un commentaire.
Le constructeur, vous êtes d'appel ne met pas en évidence que le binaire-pour-les conversions de chaînes utiliser un décodage:
String(byte[] bytes, Charset charset)
. Ce que vous voulez, c'est de ne pas utiliser de décodage à tous.Heureusement, il y a un constructeur pour qu':
String(char[] value)
.Maintenant, vous avez les données dans une chaîne de caractères, mais vous voulez à nouveau exactement comme il est. Mais devinez quoi!
getBytes(Charset charset)
C'est vrai, il y a un codage appliqué automatiquement aussi. Heureusement, il y a untoCharArray()
méthode.Si vous devez le démarrer avec les octets et à la fin avec des octets, vous devez mapper les tableaux de char d'octets:
Donc, pour résumer: la conversion entre
String
etArray[Byte]
implique l'encodage et le décodage. Si vous voulez mettre des données binaires dans une chaîne, vous devez le faire au niveau des personnages. Notez, cependant, que cela vous donnera une poubelle chaîne (c'est à dire le résultat ne sera pas bien formé UTF-16, commeString
devrait être), et donc vous feriez mieux de le lire, les personnages et la reconvertir en octets.Vous pourrait maj les octets par, disons, l'ajout de 512; puis vous obtenez un tas de valable unique
Char
points de code. Mais c'est à l'aide de 16 bits pour représenter chaque 8, 50% de l'efficacité de l'encodage. Base64 est une meilleure option pour la sérialisation binaire de données (8 bits pour représenter les 6, 75% d'efficacité).Chaîne est pour le stockage de texte qui ne sont pas des données binaires.
Dans votre codage de caractères par défaut il n'y a pas de charcter pour -127 de sorte qu'il remplace par '?' ou 63.
EDIT: Base64 est la meilleure option encore meilleure serait de ne pas utiliser le texte pour stocker des données binaires. Il peut être fait, mais pas avec n'importe quel standard de codage de caractères. c'est à dire que vous avez à faire de l'encodage vous-même.
Pour répondre à votre question, littéralement, vous pouvez utiliser votre propre codage de caractères. C'est une très mauvaise idée que tout texte est susceptible d'être codé et mutilés de la même manière que vous l'avez vu. En utilisant Base64 évite cela en utilisant des caractères qui sont en sécurité dans n'importe quel encodage.
StringOps a une méthode
getBytes
, je pense que c'est probablement ce que l'on veut réellement pour la conversion de la Chaîne de Tableau[Byte]http://www.scala-lang.org/api/2.10.2/index.html#scala.collection.immutable.StringOps
Utiliser le jeu de caractères: