Apprentissage Java 4-4_IO

Java IO

  1. Concepts de base: système d'entrée / sortie Java

  2. Entrée et sortie: la lecture des données de l'extérieur est entrée (InputStream / Reader), et le programme écrit les données vers l'extérieur en utilisant la sortie

  3. cartographie mentale
    Insérez la description de l'image ici

  4. Flux d'octets et flux de caractères:

    1. Le flux d'octets est principalement utilisé pour traiter des octets ou des objets binaires.
    2. Le flux de caractères (un caractère occupe deux octets) est conçu pour traiter des caractères ou des chaînes.
    3. L'unité de traitement du flux de caractères est un caractère Unicode de 2 octets , qui gère respectivement les caractères, les tableaux de caractères ou les chaînes, tandis que l'unité de traitement du flux d'octets est de 1 octet , qui gère les octets et les tableaux d'octets. Par conséquent, le flux de caractères est formé par la machine virtuelle Java convertissant des octets en caractères Unicode de 2 octets en tant qu'unité de caractères, ce qui lui permet de mieux prendre en charge plusieurs langues! S'il s'agit d'un fichier audio, d'une image ou d'une chanson, il est préférable d'utiliser un flux d'octets, s'il est lié au chinois (texte), il est préférable d'utiliser un flux de caractères
  5. Remarque: lors de la fermeture du flux, le flux de l'emballage extérieur doit être fermé en premier, c'est-à-dire "fermer d'abord lorsqu'il est ouvert plus tard"

    FileOutputStream fos = new FileOutputStream("f:\\qs");
    OutputStreamWriter osw = newOutputStreamWriter(fos);
    BufferedWriter bw = newBufferedWriter(osw);
    bw.write("hello qs!");
    bw.close();
    osw.close();
    fos.close();
    

1. Partie streaming

La carte mentale ci-dessus montre la relation générale entre les différents flux, et quelques explications spécifiques sont données ci-dessous

1.1 Flux de fichiers

  • FileInputStream / FileOutputStrean file byte stream, lit les fichiers en mode octet, convient à tous les types de fichiers, mais ne peut pas gérer correctement les caractères Unicode
  • Flux de caractères de fichier FileReader / FileWriter , utilisé pour le codage Unicode des fichiers texte

1.2 Flux tamponné

Le flux de tampon Java lui-même n'a pas les fonctions de lecture et d'écriture du flux IO, mais la fonction de tampon est ajoutée à d'autres flux (flux de nœuds ou autres flux de traitement) pour améliorer l'efficacité, tout comme l'empaquetage d'autres flux, donc Le flux tampon est un flux de traitement (flux de conditionnement), la taille de la zone tampon est de 8192 octets par défaut, vous pouvez également utiliser d'autres méthodes de construction pour spécifier vous-même la taille

  • Les deux flux BufferedInputStream / BufferedOutputStream sont des flux d'octets mis en mémoire tampon. Le tableau de tampons interne est utilisé pour améliorer l'efficacité du fonctionnement du flux.
  • BufferedReader / BufferedWriter met en mémoire tampon le flux de caractères, augmente le mécanisme de cache, améliore l'efficacité de la lecture et de l'écriture des fichiers texte et fournit la méthode readLine () pour faciliter la lecture par ligne. Notez qu'après avoir écrit une ligne, utilisez la méthode newLine () pour envelopper .

1.3 Flux de données

Utilisé pour décorer d'autres flux d'entrée, le flux d'entrée de données permet aux applications de lire des types de données Java de base à partir du flux d'entrée sous-jacent d'une manière indépendante de la machine.

  • DataInputStream / DataOutputStream
DataInputStream dis = new DataInputStream(InputStream in);//构造函数

//write方法
writeBytes(String str);
writeChars(String str);
writeUTF(String str);//写入数据的同时也写入长度

//特殊的读方法
ReadUTF();//知道长度才能读
readBoolean();
readByte();
readChar();
readDouble();
readFloat();
readFully(byte[] dst);
readFully(byte[] dst, int offset, int byteCount);
readInt();
readLine();
readLong();
readShort();
readUTF(DataInput in);
readUTF();
readUnsignedByte();
readUnsignedShort();
skipBytes(int count);
//以上根据名字可以知道函数作用

Étant donné que les caractères en java sont codés en Unicode et sont codés sur deux octets, writeByte () écrit simplement le contenu d'octets de poids faible de chaque caractère du caractère sur le périphérique cible. Et writeChars () écrit le contenu de deux octets de chaque caractère de la chaîne sur le périphérique cible; writeUTF () écrit la chaîne dans la longueur d'octet encodée en UTF sur le périphérique cible, puis L'encodage UTF de chaque octet.

DataInputStream fournit uniquement une méthode ReadUTF () pour renvoyer une chaîne. En effet, il est nécessaire de lire une chaîne dans un flux d'octets continu. S'il n'y a pas de marque spéciale à la fin d'une chaîne et que la longueur de la chaîne n'est pas connue, il est impossible de savoir où la chaîne est lue. La fin. Seule la méthode writeUTF () de la classe DataOutputStream
écrit la longueur de la chaîne sur le périphérique cible, afin qu'elle puisse également lire et écrire avec précision la chaîne.

1.4 Flux de repli

Toutes les données de JAVA IO sont lues dans l'ordre, c'est-à-dire que pour un flux d'entrée, elles sont lues dans l'ordre du début à la fin. Si du contenu indésirable dans le flux d'entrée est lu dans , Vous ne pouvez traiter ces contenus indésirables que via le programme. Afin de résoudre ce problème de traitement, un flux d'entrée de secours (PushbackInputStream, PushbackReader) est fourni dans JAVA, qui peut renvoyer certaines données qui ont été lues. Revenez au tampon du flux d'entrée.

  • Flux arrière d'octets PushbackInputStream / PushbackOutputStream

    public PushbackInputStream(InputStream in);//构造方法 将输入流放入到回退流之中。
    public int read() throws IOException;//读取数据。
    public int read(byte[] b,int off,int len) throws IOException;//读取指定范围的数据。
    public void unread(int b) throws IOException;//回退一个数据到缓冲区前面。
    public void unread(byte[] b) throws IOException//回退一组数据到缓冲区前面。
    public void unread(byte[] b,int off,int len) throws IOException//回退指定范围的一组数据到缓冲区前面。
    

    Le flux de secours correspond au fonctionnement du flux d'entrée

  • Flux de retour de caractères PushbackReader / PushbackWriter

1.5 Flux d'objets

  • ObjectInputStream sérialise les données d'origine de l'objet
  • ObjectOutputStream désérialise les données sérialisées

Seuls les objets prenant en charge les interfaces java.io.Serializable ou java.io.Externalizable peuvent être lus à partir du flux.

La méthode readObject () est utilisée pour lire les objets du flux. La sécurité de Java doit être utilisée pour obtenir le type souhaité. En Java, les chaînes et les tableaux sont traités comme des objets lorsqu'ils sont sérialisés, et ils sont pris lors de la lecture. Convertissez au type souhaité.

La méthode readObject () est responsable de la lecture et de l'utilisation de la méthode writeObject () correspondante pour diffuser les données écrites pour restaurer l'état de l'objet de sa classe spécifique. Cette méthode n'a pas besoin de se soucier de l'état d'appartenance à la superclasse ou à la sous-classe. La restauration de l'état concerne les champs et les objets lus à partir d'ObjectInputStream. La lecture du type de données d'origine peut être prise en charge par l'interface DataInput.

1.6 Flux de pipeline

PipedOutputStream / ** PipedInputStream ** est un flux de pipeline d'octets.

Le rôle est de permettre à plusieurs threads de communiquer entre les threads via des tuyaux. Lors de l'utilisation de la communication par canal, PipedOutputStream et PipedInputStream doivent être utilisés ensemble.

Processus d'utilisation: écrivez des données dans PipedOutputStream dans le thread A, et les données seront automatiquement envoyées à PipedInputStream correspondant à PipedOutputStream, puis stockées dans le tampon de PipedInputStream; à ce moment, le thread B lit les données dans PipedInputStream. Il peut être réalisé, communication thread A et thread B.

Remarque: n'utilisez pas PipeInpuStream et PipeOutputStream en même temps dans un thread, cela entraînera un blocage

PipedOutputStream in = new PipedOutputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);//将“管道输入流”和“管道输出流”关联起来,等价于out.connect(in),只需要调用一次。

1.7 Flux de séquence

  • SequenceInputStream / SequenceOutputStream flux de séquence d'octets, commencez par lire tous les octets du premier InputStream, puis lisez tous les octets du deuxième InputStream. C'est pourquoi il est appelé SequenceInputStream, car les instances InputStream sont lues séquentiellement.

Deux méthodes d'initialisation

SequenceInputStream sis = new SequenceInputStream(InputStream s1, InputStream s2);//通过两个参数初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2)

SequenceInputStream(Enumeration<? extends InputStream> e);//通过枚举对象来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数

//组合多个流
InputStream input1 = new FileInputStream("1.txt");
InputStream input2 = new FileInputStream("2.txt");
InputStream input3 = new FileInputStream("3.txt");

Vector<InputStream> streams = new Vector<>();
streams.add(input1);
streams.add(input2);
streams.add(input3);

//利用 Vector 对象的 elements() 方法返回 enumeration 对象
SequenceInputStream sequenceInputStream = new SequenceInputStream(streams.elements());

1.8 Array Stream

Les données sont écrites dans le tableau d'octets, le tampon augmentera automatiquement lorsque les données sont écrites, il est invalide pour fermer le flux, il n'y aura pas d'exceptions lorsque la méthode est appelée après la fermeture du flux

  • ByteArrayInputStream / ** ByteArrayOutputStream ** Flux de tableau d'octets, crée un tampon de tableau d'octets en mémoire et enregistre les données lues à partir du flux d'entrée dans le tampon de tableau d'octets.

    write(int b);//写入指定的字节到此字节输出流中
    write(byte b[], int off, int len);//从指定数组的下标off开始写入len个字节到该输出流中
    writeTo(OutputStream out);//将此字节输出流的内容写入到指定的输出流中
    reset();//重置此字节输出流,废弃此前存储的数据
    toByteArray();//对输出流的数据进行检索
    
  • CharArrayReader / CharArrayWriter flux de tableau de caractères, l'opération est en caractères

    write(int oneChar);//的作用将int类型的oneChar换成char类型,然后写入到CharArrayWriter中。
    write(char[] buffer, int offset, int len);//是将字符数组buffer写入到输出流中,offset是从buffer中读取数据的起始偏移位置,len是读取的长度。
    write(String str, int offset, int count);//是将字符串str写入到输出流中,offset是从str中读取数据的起始位置,count是读取的长度。
    append(char c);//的作用将char类型的c写入到CharArrayWriter中,然后返回CharArrayWriter对象。注意:append(char c)与write(int c)都是将单个字符写入到CharArrayWriter中。它们的区别是,append(char c)会返回CharArrayWriter对象,但是write(int c)返回void。
    ppend(CharSequence csq, int start, int end);//的作用将csq从start开始(包括)到end结束(不包括)的数据,写入到CharArrayWriter中。注意:该函数返回CharArrayWriter对象!
    append(CharSequence csq);//的作用将csq写入到CharArrayWriter中。注意:该函数返回CharArrayWriter对象!
    writeTo(OutputStream out);//将该“字符数组输出流”的数据全部写入到“输出流out”中。
    

1.9 Flux de conversion

InputStreamReader / OutputStreamWriter

Le flux Java IO fournit deux flux de conversion pour convertir les flux d'octets en flux de caractères.

InputStreamReader est utilisé pour convertir les flux d'entrée d'octets en flux d'entrée de caractères, et OutputStreamWriter est utilisé pour convertir les flux de sortie d'octets en flux de sortie de caractères. L'utilisation du flux de conversion peut éviter dans une certaine mesure les caractères
déformés, et vous pouvez également spécifier le jeu de caractères utilisé pour l'entrée et la sortie, OutputStreamWriter, pour convertir le flux de sortie d'octets en un flux de sortie de caractères. Créez un OutputStreamWriter qui utilise le jeu de caractères spécifié. Si vous ne spécifiez pas de jeu de caractères, utilisez le jeu de caractères par défaut pour créer un OutputStreamWriter. Vous n'avez pas besoin de fermer OutputStream après la conversion

//输出流中的方法
flsh();//刷新该流的缓冲
close();//关闭此流,关闭前需要刷新
getEncoding();//获取此流使用的字符编码的名称。
write(char[] ,int offset ,int length);//写入字符数组的某一部分
write(String ,int offset ,int length);//写入字符串的某一部分
write(String );//写入单个字符

Deuxièmement, la partie non-streaming

2.1 Autorisation sérialisable

Utilisé pour les autorisations sérialisables. L'exécution sérialisable contient un nom (également appelé "nom cible"), mais pas de liste d'opérations.

2.2 Fichier

Les classes de fichiers Java représentent les noms de fichiers et les noms de chemins de répertoire de manière abstraite. Cette classe est principalement utilisée pour la création de fichiers et de répertoires, la recherche de fichiers et la suppression de fichiers, etc.

Numéro de série Description de la méthode
1 public String getName () renvoie le nom du fichier ou du répertoire représenté par ce chemin abstrait.
2 public String getParent () renvoie la chaîne de nom de chemin du nom de chemin parent de ce nom de chemin abstrait, ou si le nom de chemin ne spécifie pas de répertoire parent, il renvoie null.
3 public File getParentFile () renvoie le nom de chemin abstrait du nom de chemin parent de ce nom de chemin abstrait, ou si le nom de chemin ne spécifie pas de répertoire parent, il retourne null.
4 public String getPath () convertit ce nom de chemin abstrait en une chaîne de nom de chemin.
5 public boolean isAbsolute () teste si ce nom de chemin abstrait est un nom de chemin absolu.
6 public String getAbsolutePath () renvoie la chaîne de nom de chemin absolu du nom de chemin abstrait.
7 public boolean canRead () teste si l'application peut lire le fichier représenté par ce chemin abstrait.
8 public boolean canWrite () teste si l'application peut modifier le fichier représenté par ce chemin abstrait.
9 public boolean exists () teste si le fichier ou le répertoire représenté par ce nom de chemin abstrait existe.
dix public boolean isDirectory () teste si le fichier représenté par ce chemin abstrait est un répertoire.
11 public boolean isFile () teste si le fichier indiqué par ce chemin abstrait est un fichier standard.
12 public long lastModified () renvoie l'heure à laquelle le fichier représenté par ce chemin abstrait a été modifié pour la dernière fois.
13 public long length () renvoie la longueur du fichier représenté par ce chemin abstrait.
14 public boolean createNewFile () jette IOException Si et seulement s'il n'y a pas de fichier avec le nom spécifié par ce chemin abstrait, créez de manière atomique un nouveau fichier vide spécifié par ce chemin abstrait.
15 public boolean delete () supprime le fichier ou le répertoire indiqué par ce chemin abstrait.
16 public void deleteOnExit () demande de supprimer le fichier ou le répertoire indiqué par ce nom de chemin abstrait lorsque la machine virtuelle s'arrête.
17 public String [] list () renvoie un tableau de chaînes composé des noms de fichiers et de répertoires dans le répertoire représenté par ce chemin abstrait.
18 public String [] list (FilenameFilter filter) renvoie un tableau de chaînes composé des noms de fichiers et de répertoires contenus dans le répertoire. Ce répertoire est représenté par un nom de chemin abstrait qui satisfait le filtre spécifié.
19 public File [] listFiles () retourne un tableau de chemins abstraits qui représentent les fichiers dans le répertoire représenté par ce chemin abstrait.
20 public File [] listFiles (filtre FileFilter) renvoie un tableau de chemins abstraits représentant les fichiers et répertoires dans le répertoire représenté par ce chemin abstrait, et ces chemins satisfont un filtre spécifique.
21 public boolean mkdir () crée le répertoire spécifié par ce nom de chemin abstrait.
22 public boolean mkdirs () crée le répertoire spécifié par ce chemin abstrait, y compris le répertoire parent qui est nécessaire mais qui n'existe pas.
23 public boolean renameTo (File dest) renomme le fichier représenté par ce chemin abstrait.
24 public boolean setLastModified (long time) définit l'heure de la dernière modification du fichier ou du répertoire spécifié par ce nom de chemin abstrait.
25 public boolean setReadOnly () marque le fichier ou le répertoire spécifié par ce chemin abstrait afin qu'il ne puisse être lu.
26 public static File createTempFile (String prefix, String suffix, File directory) jette IOException Crée un nouveau fichier vide dans le répertoire spécifié et utilise le préfixe et la chaîne de suffixe donnés pour générer son nom.
27 public static File createTempFile (String prefix, String suffix) throws IOException Crée un fichier vide dans le répertoire de fichiers temporaires par défaut, en utilisant le préfixe et le suffixe donnés pour générer son nom.
28 public int compareTo (File pathname) compare deux chemins abstraits par ordre alphabétique.
29 public int compareTo (Object o) Compare les chemins abstraits avec l'objet donné dans l'ordre alphabétique.
30 public boolean equals (Object obj) teste si ce chemin abstrait est égal à l'objet donné.
31 public String toString () renvoie la chaîne de nom de chemin de ce nom de chemin abstrait.

2.3 RandomAccessFile

RandomAccessFile implémente la plupart des méthodes de flux d'entrée et de sortie de fichier, mais dans l'implémentation sous-jacente, il implémente les interfaces DataInput et DataOutput, pas FileInputStream et FileOutputStream. RandomAccessFile utilise de nombreuses méthodes natives pour implémenter les opérations sur les fichiers, et de nombreuses méthodes natives se chevauchent avec le flux d'entrée

2.4 FileDescriptor

FileDescriptor peut être utilisé pour représenter des fichiers ouverts, des sockets ouverts, etc.

当FileDescriptor表示文件来说,当FIleDescriptor表示某文件时,我们可以通俗的将FIleDescriptor看成该文件。但是,我们不能直接通过FIleDescriptor对该文件进行操作;若需要通过FIleDescriptor对该文件进行操作,则需要创建FileDescriptor对应的FileOutputStream,再对文件进行操作。

三、补充

  1. 在文件中,换行为 \r\n

  2. 路径分隔符, linux文件路径分隔符为 / ,windows的文件路径分隔符为 \ 。System.getProperty(“file.separator”)

  3. 字节流和字符流的区别:

    1. 读写单位不同:字节流以字节(8 bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
    2. 处理对象不同:字节流能处理所有类型的数据(如图片、avi 等),而字符流只能处理字符类型的数据。
    3. 字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用 colse() 方法时,信息已经输出了,而字符流只有在调用 close() 方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用 flush() 方法。
  4. 节点流和处理流:Java io 分类方式有很多,根据是否直接处理数据,Java io又分为节点流和处理流,节点流是真正直接处理数据的;处理流是装饰加工节点流的。

  5. 什么叫对象序列化,什么是反序列化,实现对象序列化需要做哪些工作?

    • 对象序列化:将对象以二进制的形式保存在硬盘上;
    • 反序列化:将二进制的文件转化为对象读取;
    • 实现 serializable 接口可以实现对象序列化,其中没有需要实现的方法,implements Serializable 只是为了标注该对象是可被序列化的
  6. 什么是 Filter 流有哪些?

    FilterStream 是一种 IO 流,主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能等。在 java.io 包中主要由 4 个可用的 filter Stream。两个字节 filter stream,两个字符 filter stream。FilterStream 是抽象类不能被是咯话,其子类有:DataInputStream、BufferedInputStream、PushbackInputStream

四、NIO

NIO和传统IO(一下简称IO)之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

Divers flux d'E / S sont bloqués . Cela signifie que lorsqu'un thread appelle read () ou write (), le thread est bloqué jusqu'à ce que certaines données soient lues ou que les données soient complètement écrites. Le fil ne peut rien faire pendant cette période. Le mode non bloquant de NIO permet à un thread d'envoyer une demande de lecture de données à partir d'un canal, mais il ne peut obtenir que les données actuellement disponibles. S'il n'y a actuellement aucune donnée disponible, il n'obtiendra rien. Au lieu de garder le thread bloqué, le thread peut continuer à faire d'autres choses jusqu'à ce que les données deviennent lisibles. Il en va de même pour les écritures non bloquantes. Un thread demande d'écrire des données sur un certain canal, mais n'a pas besoin d'attendre qu'il soit complètement écrit, le thread peut faire d'autres choses en même temps. Les threads utilisent généralement le temps d'inactivité des E / S non bloquantes pour effectuer des opérations d'E / S sur d'autres canaux, de sorte qu'un seul thread peut désormais gérer plusieurs canaux d'entrée et de sortie.

Je suppose que tu aimes

Origine blog.csdn.net/Sky_Coolssy/article/details/108855718
conseillé
Classement