4.2 字节流与字符流

在Java中,有两种基本的数据流类型:字节流和字符流。字节流处理原始二进制数据,而字符流处理Unicode字符。本章节我们将学习字节流与字符流的基本概念以及如何使用它们进行文件的输入输出操作。

4.2.1 字节流

字节流处理原始二进制数据,分为输入字节流(InputStream)和输出字节流(OutputStream)。它们都是抽象类,不能直接实例化,但有很多实现类可用。以下是一些常用的字节流类:

  • FileInputStream: 从文件中读取字节
  • FileOutputStream: 向文件中写入字节
  • ByteArrayInputStream: 从字节数组中读取字节
  • ByteArrayOutputStream: 向字节数组中写入字节
  • BufferedInputStream: 缓冲输入字节流
  • BufferedOutputStream: 缓冲输出字节流
4.2.1.1 使用FileInputStream和FileOutputStream

我们先来看一个使用FileInputStreamFileOutputStream进行文件复制的例子:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
 public static void main(String[] args) {
 try {
 FileInputStream fis = new FileInputStream("input.txt");
 FileOutputStream fos = new FileOutputStream("output.txt");
 int data;
 while ((data = fis.read()) != -1) {
 fos.write(data);
 }
 fis.close();
 fos.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

这段代码首先创建了一个FileInputStream对象来读取名为input.txt的文件,并创建一个FileOutputStream对象来将数据写入名为output.txt的文件。然后,通过循环调用read()方法从FileInputStream中读取一个字节,然后用write()方法将它写入FileOutputStream。当read()方法返回-1时,表示已经到达文件末尾,循环结束。最后,不要忘记关闭输入输出流。

4.2.1.2 使用BufferedInputStream和BufferedOutputStream

为了提高读写效率,我们可以使用BufferedInputStreamBufferedOutputStream。它们对字节流进行缓冲,以减少对底层数据源或目标的实际读写次数。下面是使用缓冲字节流进行文件复制的例子:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
 public static void main(String[] args) {
 try {
 FileInputStream fis = new FileInputStream("input.txt");
 BufferedInputStream bis = new BufferedInputStream(fis);
 FileOutputStream fos = new FileOutputStream("output.txt");
 BufferedOutputStream bos = new BufferedOutputStream(fos);
 int data;
 while ((data = bis.read()) != -1) {
 bos.write(data);
 }
 bis.close();
 bos.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

4.2.2 字符流

字符流处理Unicode字符,分为输入字符流(Reader)和输出字符流(Writer)。它们同样是抽象类,以下是一些常用的字符流类:

  • FileReader: 从文件中读取字符
  • FileWriter: 向文件中写入字符
  • CharArrayReader: 从字符数组中读取字符
  • CharArrayWriter: 向字符数组中写入字符
  • BufferedReader: 缓冲输入字符流
  • BufferedWriter: 缓冲输出字符流
4.2.2.1 使用FileReader和FileWriter

我们来看一个使用FileReaderFileWriter进行文件复制的例子:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
 public static void main(String[] args) {
 try {
 FileReader fr = new FileReader("input.txt");
 FileWriter fw = new FileWriter("output.txt");
 int data;
 while ((data = fr.read()) != -1) {
 fw.write(data);
 }
 fr.close ();
 fw.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

这段代码与之前的字节流示例类似,但这里使用的是FileReaderFileWriter,它们处理字符而非字节。这样做的好处是,我们可以在读取和写入文本文件时正确处理Unicode字符。

4.2.2.2 使用BufferedReader和BufferedWriter

同样,我们可以使用BufferedReaderBufferedWriter提高字符流的读写效率。下面是一个使用缓冲字符流进行文件复制的例子:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
 public static void main(String[] args) {
 try {
 FileReader fr = new FileReader("input.txt");
 BufferedReader br = new BufferedReader(fr);
 FileWriter fw = new FileWriter("output.txt");
 BufferedWriter bw = new BufferedWriter(fw);
 int data;
 while ((data = br.read()) != -1) {
 bw.write(data);
 }
 br.close();
 bw.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

小结

我们学习了字节流与字符流的基本概念以及如何使用它们进行文件的输入输出操作。字节流处理原始二进制数据,字符流处理Unicode字符。在实际编程中,可以根据数据类型选择合适的流进行操作。同时,使用缓冲流可以提高读写效率。

请务必在操作完成后关闭流,以避免资源泄漏。从Java 7开始,可以使用try-with-resources语句自动关闭资源。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
 public static void main(String[] args) {
 try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));
 BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
 int data;
 while ((data = br.read()) != -1) {
 bw.write(data);
 }
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

以上代码使用了try-with-resources语句,无需手动关闭资源。当try语句块结束时,资源会自动关闭。
推荐阅读:

https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA

https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g

作者:移动安全星球原文地址:https://segmentfault.com/a/1190000043848190

%s 个评论

要回复文章请先登录注册