J'ai utilisé RandomAccessFile
pour lire une byte
à partir d'un fichier texte.
public static void readFile(RandomAccessFile fr) {
byte[] cbuff = new byte[1];
fr.read(cbuff,0,1);
System.out.println(new String(cbuff));
}
Pourquoi est-ce que je vois un personnage complet en train d'être lu?
Un char
représente un caractère en Java (*). Il a une taille de 2 octets (du moins c'est ce que suggère la plage de valeurs valides).
Cela ne signifie pas nécessairement que chaque représentation d'un caractère est longue de 2 octets. En fait, de nombreux encodages ne réservent qu'un octet pour chaque caractère (ou utilisent un octet pour les caractères les plus courants).
Lorsque vous appelez le constructeur String(byte[])
, vous demandez à Java de convertir le byte[]
en String
à l'aide du codage par défaut de la plate-forme. Comme le codage par défaut de la plate-forme est généralement un codage sur 1 octet tel que ISO-8859-1 ou un codage de longueur variable tel que UTF-8, il peut facilement convertir ce 1 octet en un seul caractère.
Si vous exécutez ce code sur une plate-forme qui utilise UTF-16 (ou UTF-32 ou UCS-2 ou UCS-4 ou ...) comme codage par défaut de la plate-forme, vous n'obtiendrez pas un résultat valide (vous obtiendrez String
contenant le caractère de remplacement Unicode à la place).
C'est l'une des raisons pour lesquelles vous ne devriez pas dépendre du codage par défaut de la plate-forme: lors de la conversion entre byte[]
et char[]
String
ou entre InputStream
et Reader
ou entre OutputStream
et Writer
, vous devez toujours spécifier le codage que vous souhaitez utiliser. Sinon, votre code dépend de la plate-forme.
(*) ce n'est pas _/entièrement vrai: une char
représente un codepoint UTF-16. Les codecs one ou two UTF-16 représentent des codages Unicode. Un point de code Unicode habituellement représente un caractère, mais parfois, plusieurs points de code Unicode sont utilisés pour constituer un seul caractère. Mais l’approximation ci-dessus est suffisamment proche pour permettre de discuter du sujet.
Java stocke tous ses "caractères" en interne sous la forme de deux octets. Cependant, lorsqu'ils deviennent des chaînes, etc., le nombre d'octets dépend de votre codage.
Certains caractères (ASCII) sont à octet unique, mais beaucoup d’autres sont à octets multiples.
Java supporte Unicode, donc selon:
La valeur maximale prise en charge est "\ uFFFF" (hex FFFF, dec 65535) ou 11111111 11111111 binaire (deux octets).
Le constructeur String(byte[] bytes)
prend les octets dans la mémoire tampon et les code en caractères.
Il utilise le jeu de caractères par défaut de la plateforme pour encoder des octets en caractères. Si vous le savez, votre fichier contient du texte codé dans un jeu de caractères différent, vous pouvez utiliser la fonction String(byte[] bytes, String charsetName)
pour utiliser le codage correct (des octets aux caractères).
Dans le fichier texte ASCII, chaque caractère ne représente qu'un octet.
On dirait que votre fichier contient des caractères ASCII codés dans un octet seulement. Si le fichier texte contient des caractères non-ASCII, par ex. 2 octets UTF-8, alors vous obtenez uniquement le premier octet, pas le caractère entier.
Il y a quelques bonnes réponses ici mais je voulais préciser que jvm est libre de stocker une valeur de caractère dans tout espace de taille> = 2 octets.
Sur de nombreuses architectures, l'accès à la mémoire non alignée est pénalisé, de sorte qu'un caractère peut facilement être complété sur 4 octets. Un caractère volatile peut même être ajouté à la taille de la ligne de cache du processeur pour empêcher tout faux partage. https://en.wikipedia.org/wiki/False_sharing
Il peut être non intuitif pour les nouveaux programmeurs Java qu'un tableau de caractères ou une chaîne ne sont PAS simplement plusieurs caractères. Vous devriez apprendre et penser les chaînes et les tableaux distinctement de "plusieurs caractères".
Je tiens également à souligner que les caractères Java sont souvent mal utilisés. Les gens ne réalisent pas qu'ils écrivent un code qui ne gérera pas correctement les points de code de plus de 16 bits.
Java attribue 2 caractères sur 2 au caractère suivant UTF-16. Il occupe au minimum 2 octets lors de l’enregistrement d’un caractère et au maximum 4 octets. Il n'y a pas de 1 octet ou 3 octets de stockage pour le caractère.