Que dois-je faire si Java io est tronqué ? Problèmes d'IO et de chinois tronqués en Java
C'est la première fois que je publie ce genre de blog, donc j'ai eu du mal à savoir par où commencer, alors autant aller directement au sujet et en enregistrer quelques-uns de mes expériences résumées. Commençons par les plus simples. Je viens de commencer à apprendre et j'espère pouvoir m'y tenir lentement et écrire un contenu meilleur et plus significatif à l'avenir.
En fait, nous ne rencontrons pas beaucoup de problèmes avec les caractères chinois tronqués au travail, car l'entreprise a unifié l'encodage des fichiers pour faciliter le développement. Mais je pense qu’il est nécessaire de comprendre un peu ses principes.
Recommandation : "apprentissage Java"
IO est le flux d'entrée et de sortie Si compris en termes orientés objet, il s'agit de l'entrée. et objets de flux de sortie. Principalement utilisé pour faire fonctionner des objets fichier. Parlons donc un peu du concept de fichiers, c'est-à-dire des objets File. En Java, File n'est pas un fichier spécifique auquel nous faisons référence dans la vie quotidienne, mais un objet chemin, par exemple File file=new File("D:\aaa"); dossier, le chemin n'existe peut-être pas, mais ce code crée en effet un objet File représentant le chemin. Cette façon d’écrire n’est tout simplement pas couramment utilisée. Parce que nous opérons généralement davantage sur un texte, une image, etc., comme File f=new File("aaa.txt");
Ce qui précède a brièvement mentionné ce que sont IO et File, et nous en parlerons Ensuite, parlez de la façon dont ces images, textes, vidéos et autres informations sont stockés sur nos périphériques de stockage.
Ma compréhension personnelle est que quel que soit le type de fichier, il est enregistré sous forme binaire. L'unité minimale est de 1 octet, composé de 8 bits 01. Donc, si nous voulons copier un fichier, il suffit d'exploiter le flux d'octets, c'est-à-dire de récupérer tous les octets d'un fichier et de les écrire dans un autre fichier. En fait, c'est théoriquement possible, mais pour des fichiers de caractères de ce type. sont plutôt particuliers.
C'est pourquoi il y a un problème avec les caractères chinois tronqués. Tout le monde connaît la table de codes ASCII, ou du moins en a entendu parler. Elle doit être considérée comme une table de codes apparue très tôt, elle n'était utilisée que pour représenter 26 lettres anglaises et quelques symboles spéciaux (car les ordinateurs ne reconnaissent que). binaire, il faut donc remplacer les caractères par les octets correspondants pour former une table de codes).
Mais avec le développement des ordinateurs, l'ASCII n'est peut-être pas suffisant, et de nombreux pays peuvent avoir leurs propres schémas de codage, c'est pourquoi différentes tables de codage ont vu le jour. Les plus courants sont GBK et UTF-8, et le codage par défaut utilisé dans jvm est le codage unicode, c'est-à-dire que 2 octets représentent un caractère chinois, mais UTF-8 n'est pas nécessairement le cas. Il peut s'agir de 3 octets pour représenter un caractère chinois. , ou plus. Un problème se pose donc. Le nombre et le contenu des octets de code correspondants pour le même caractère chinois dans différentes tables de codes sont différents.
Alors comment le résoudre ?
Lorsque nous copions une image du disque A vers le disque B, il nous suffit de récupérer tous les octets de A vers B. Mais il est effectivement possible d’opérer un texte de la même manière, à condition que les encodages de texte en A et B doivent être les mêmes. Parce qu'il n'y a pas de problème de codage d'octets dans les images. Mais que dois-je faire si je veux transmettre du chinois depuis le réseau ou le serveur ? Cela ne peut certainement pas être réalisé avec seulement des octets (car nous ne pouvons pas modifier manuellement l'encodage du fichier si nous rencontrons des problèmes). Par conséquent, Java fournit un objet flux de caractères, qui ajoute des paramètres de codage sur la base du flux d'octets pour résoudre le problème des caractères tronqués.
Sans plus tarder, utilisons quelques petits cas pour illustrer :
1 Tout d'abord, créez aa.txt et bb.txt sous le projet en cours. Écrivez simplement quelques caractères chinois en aa. Vous constaterez que les deux méthodes peuvent implémenter
a, en utilisant le flux de caractères
FileReader fr=new FileReader("aa.txt"); FileWriter fw=new FileWriter("bb.txt"); int c; while((c=fr.read())!=-1){ fw.write(c); } fr.close(); fw.close();
b et en utilisant le flux d'octets
FileInputStream fis=new FileInputStream("aa.txt"); FileOutputStream fos=new FileOutputStream("bb.txt"); int b; while((b=fis.read())!=-1){ fos.write(b); } fis.close(); fos.close();
2 À ce moment, si l'encodage est effectué. La méthode de aa est S'il s'agit d'UTF-8, alors changeons l'encodage de bb en GBK et voyons si nous exécutons à nouveau les deux méthodes ci-dessus, tous les caractères sont tronqués.
La raison est qu'en raison des différentes méthodes d'encodage des deux fichiers, la table des codes chinois est différente, donc le code est tronqué.
3, ainsi lorsque les méthodes d'encodage des deux fichiers sont différentes, on peut préciser l'encodage correspondant au fichier lors de la lecture et de l'écriture.
L'implémentation est la suivante :
InputStreamReader isr=new InputStreamReader(new FileInputStream("aa.txt"),"utf-8"); OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("bb.txt"),"gbk"); char[] arr=new char[1024]; int len; while((len=isr.read(arr))!=-1){ String s=new String(arr,0,len); System.out.println(s); osw.write(s); } isr.close(); osw.close();
Bien que le code soit très simple, expliquons-le brièvement À partir de l'API, nous pouvons constater que InputStreamReader et OutputStreamWriter sont tous deux des objets qui opèrent sur des caractères. Continuez avec Reader et Writer.
est principalement utilisé pour convertir des octets en caractères et des caractères en octets. Ainsi, la construction permet également de constater que ce qui est transmis est un objet de flux d'octets. Utilisez UTF-8 pour lire le flux d'octets et le convertir en caractères, puis convertissez les caractères en codage gbk et écrivez-les en octets.
Les lignes suivantes ne seront pas expliquées, ce sont toutes des méthodes de base. Ce qui est transmis dans la construction, c'est l'objet de classe interne anonyme et le motif de conception décoratif. Vous pouvez simplement comprendre cette méthode d'écriture.
Il existe en fait de nombreuses classes utiles pour les flux d'octets et les flux de caractères, telles que BufferedInputStream, BufferedReader, etc., que je n'entrerai pas dans les détails.
Concernant les problèmes de codage de jvm et de la plateforme système, je ne l'expliquerai pas ici.
Vous pouvez l'essayer avec String et observer les problèmes de bytecode et d'encodage de la chaîne lors de la compilation et de l'exécution.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!