目录
IO流就是存入和读取数据的解决方案,并且他是一个知识点很多的章节,因此我们关于IO流的介绍会分为多篇来进行详解,而掌握好IO流可以大大提高我们的效率,简化我们的代码执行效率。
在前文我们知道,如果我们想要实现对于程序的存档功能,就一共需要实现两个功能:
将数据存到文件当中,这也就是我们上一篇文章File类的作用
实现程序对文件数据的读取功能,这也就是我们接下来几篇所介绍的IO流的作用
在Java中,IO流(Input/Output Stream)是用于处理输入和输出的机制。它提供了读写数据的方式,允许程序与文件、网络等交互。Java中的IO流分为字节流和字符流两种类型。
字节流操作以字节为单位进行输入和输出。字节流主要由InputStream和OutputStream两个抽象类及其各种实现类组成。常见的字节流类包括FileInputStream、FileOutputStream、ByteArrayInputStream、ByteArrayOutputStream等。
字符流操作以字符为单位进行输入和输出,它可以直接操作Unicode字符。字符流主要由Reader和Writer两个抽象类及其各种实现类组成。常见的字符流类包括FileReader、FileWriter、BufferedReader、BufferedWriter等。
字节流可以操作所有类型的文件,字符流只能操作纯文本文件。
1.字节流类:
1.FileOutputStream
FileOutputStream是Java IO库中用于将数据写入文件的字节输出流。它继承自OutputStream类并添加了一些特定于文件输出的方法。通过FileOutputStream,我们可以将字节数据写入本地文件,可以是单个字节,字节数组或部分字节数组。
使用FileOutputStream的基本步骤如下:
-
创建FileOutputStream对象:通过调用FileOutputStream的构造函数,指定要写入的文件路径和文件名称。例如:
FileOutputStream fos = new FileOutputStream("file.txt");
-
写入数据:使用FileOutputStream提供的write()方法将数据写入文件。有多个重载的write()方法可以使用。常见的方法包括:
void write(int b)
:将指定的字节写入文件。void write(byte[] b)
:将指定字节数组中的所有数据写入文件。void write(byte[] b, int off, int len)
:将指定字节数组中的部分数据写入文件,参数off表示数组的起始位置,参数len表示要写入的字节数。
例如,使用write(byte[])方法将字符串数据写入文件:
String data = "Hello, World!";byte[] bytes = data.getBytes();fos.write(bytes);
-
刷新数据:如果需要将数据立即写入磁盘而不是等待缓冲区满或关闭流时才写入,可以调用flush()方法。例如:
fos.flush();
-
关闭流:使用完毕后,务必关闭FileOutputStream以释放资源。可以使用close()方法关闭。例如:
fos.close();
完整的示例代码如下:
import java.io.FileOutputStream;import java.io.IOException;public class FileOutputStreamExample { public static void main(String[] args) { try { FileOutputStream fos = new FileOutputStream("file.txt"); String data = "Hello, World!"; byte[] bytes = data.getBytes(); fos.write(bytes); fos.flush(); fos.close(); System.out.println("Data has been written to the file."); } catch (IOException e) { e.printStackTrace(); } }}
FileOutputStream还提供了其他一些方法,如getFD()用于获取与流关联的文件描述符,以及在特定位置写入数据的seek()方法等。
需要注意的是,使用FileOutputStream时可能会抛出IOException或FileNotFoundExceptio等异常,因此在使用时要进行适当的异常处理。
2.FileInputStream
FileInputStream是Java IO库中用于从文件中读取数据的字节输入流。它继承自InputStream类,并提供了一些特定于文件输入的方法。通过FileInputStream,我们可以从文件中读取字节数据,可以是单个字节,也可以是一组字节。
使用FileInputStream的基本步骤如下:
-
创建FileInputStream对象:通过调用FileInputStream的构造函数,指定要读取的文件路径和文件名称。例如:
FileInputStream fis = new FileInputStream("file.txt");
-
读取数据:使用FileInputStream提供的read()方法来读取数据。有多个重载的read()方法可以使用。常见的方法包括:
int read()
:读取一个字节的数据并返回该字节数据的整数表示(0-255),当到达文件末尾时返回-1。int read(byte[] b)
:从文件中读取一定数量的字节,并将其存储在指定的字节数组b中,并返回实际读取的字节数。读取到文件末尾时返回-1。int read(byte[] b, int off, int len)
:从文件中读取最多len个字节到指定的字节数组b中,从数组的偏移量off开始,并返回实际读取的字节数。读取到文件末尾时返回-1。
例如,使用read(byte[])方法读取文件中的数据并将其打印到控制台:
FileInputStream fis = new FileInputStream("file.txt");byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = fis.read(buffer)) != -1) { System.out.write(buffer, 0, bytesRead);}
-
关闭流:使用完毕后,务必关闭FileInputStream以释放资源。可以使用close()方法关闭。例如:
fis.close();
完整的示例代码如下:
import java.io.FileInputStream;import java.io.IOException;public class FileInputStreamExample { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("file.txt"); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { System.out.write(buffer, 0, bytesRead); } fis.close(); } catch (IOException e) { e.printStackTrace(); } }}
FileInputStream还提供了其他一些方法,例如available()返回还剩下多少可读取的字节数,skip(long n)用于跳过指定数量的字节等。
需要注意的是,使用FileInputStream时可能会抛出IOException或FileNotFoundException等异常,因此在使用时要进行适当的异常处理。
2.字符流类:
字符流可以用来解决读码问题,因为汉字的编码并不是一个字节大小,而如果我们在读码的时候按照字节流进行输出的话,就会错误的把汉字编码转化成为乱码,因此我们设计了字符流,使得读码的时候不是按照字节来读取,而是字符。
在Java中,字符流类是用于读取和写入字符数据的类集合。它们都位于java.io包中,常用的字符流类包括:
-
FileReader和FileWriter:用于读取和写入字符文件的字符流类。
- FileReader:用于读取字符文件(如文本文件)。它以字符为单位读取文件的内容。
- FileWriter:用于写入字符文件(如文本文件)。它以字符为单位将数据写入文件。
import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class CharacterStreamsExample { public static void main(String[] args) { try { // 创建FileReader对象并指定要读取的文件路径 FileReader reader = new FileReader("input.txt"); // 创建FileWriter对象并指定要写入的文件路径 FileWriter writer = new FileWriter("output.txt"); int character; // 逐字符读取文件内容并写入到输出文件中 while ((character = reader.read()) != -1) { writer.write(character); } // 关闭流 reader.close(); writer.close(); System.out.println("文件复制完成!"); } catch (IOException e) { e.printStackTrace(); } }}
-
BufferedReader和BufferedWriter:提供了缓冲功能,加速字符输入输出操作。
- BufferedReader:用于读取字符数据,并提供了缓冲功能,可以提高读取效率。
- BufferedWriter:用于写入字符数据,并提供了缓冲功能,可以提高写入效率。
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class BufferedCharacterStreamsExample { public static void main(String[] args) { try { // 创建BufferedReader对象并指定要读取的文件路径 BufferedReader reader = new BufferedReader(new FileReader("input.txt")); // 创建BufferedWriter对象并指定要写入的文件路径 BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt")); String line; // 逐行读取文件内容并写入到输出文件中 while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); // 写入换行符 } // 关闭流 reader.close(); writer.close(); System.out.println("文件复制完成!"); } catch (IOException e) { e.printStackTrace(); } }}
-
InputStreamReader和OutputStreamWriter:用于处理字节流和字符流之间的转换。
- InputStreamReader:将字节流转换为字符流。它可以指定字符集,将字节解码为字符。
- OutputStreamWriter:将字符流转换为字节流。它可以指定字符集,将字符编码为字节。
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class EncodingExample { public static void main(String[] args) { try { // 使用InputStreamReader将字节流转换为字符流 FileInputStream fis = new FileInputStream("input.txt"); InputStreamReader reader = new InputStreamReader(fis, "UTF-8"); int data; while ((data = reader.read()) != -1) { System.out.print((char) data); } reader.close(); // 使用OutputStreamWriter将字符流转换为字节流 FileOutputStream fos = new FileOutputStream("output.txt"); OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8"); writer.write("你好,世界!"); writer.close(); } catch (IOException e) { e.printStackTrace(); } }}
本文我们介绍了IO流中的两大类:字节流和字符流类的使用方法,在实际的代码书写中,我们也要根据实际情况来确定哪一个更加适合。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!