——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
一、概述
IO 流即输入输出流,用于将来自键盘、文件和内存的字节和字符输出到硬盘、屏幕和文件。Java 提供不同的类和方法,用于处理字符流和字节流。处理字符流的类包括 FileWriter、FileReader 等,处理字节流的类包括 InputStream、OutputStream 等,还有将字节流转换为字符流的 InputStreamReader、OutputStreamWriter,以及用于加速读写操作的 BufferedReader 和 BufferedWriter 装饰类等。
二、IO 异常
大部分处理 IO 的类中的方法会抛出 IO 异常,因此在调用这些方法时需要对异常进行处理。
// 使用 FileWriter 中的 write 方法将一段字符串写入文件,并处理可能出现的异常
import java.io.*; //导入 io 中的类
class Demo {
public static void main (String[] args) {
try {
// 创建一个输入流
FileWriter fw = new FileWriter("1.txt");
fw.write("abc");//写入字符串
}
catch (IOException e) {
throw new RuntimeException("写入失败");
}
finally {
if (fw != null) {
try {
fw.close();//刷新缓冲并关闭流
}
catch (IOException e) {
throw new RuntimeException("关闭流失败");
}
}
}
}
}
通过上面的代码,可以在出现 IO 异常时抛出运行时异常,中断程序运行。这是 IO 异常的正常处理方式,在后面的示例中,为了使代码紧凑,将采取抛出异常的处理方式。
三、字符流
(1)FileWriter 和 FileReader
使用 FileWriter 对象可以使用父类 Writer 类中的 write 方法将字符流输入到文件中,其可以写入单个字符、字符数组和字符串。
// 使用 FileWriter 向文件中写入字符
import java.io.*;
class Demo {
public static void main (String[] args) throws IOException {
// 创建写入文件 1.txt 的输入流
FileWriter fw = new FileWriter("1.txt");
fw.write(97);//写入单个字符
fw.write("abc");//写入字符串
fw.write("abc",0,1);//写入字符串的一部分
char[] ch = {'a','b','c','d'};
fw.write(ch);// 写入字符数组
fw.write(ch,0,2);// 写入字符数组的一部分
fw.flush();//刷新缓冲
fw.close();//关闭缓冲
}
}
输出字符流时,需要刷新缓冲才能将字符输出到最终的目标,因此需要使用 flush 或 close 方法刷新缓冲,其中 close 方法是在关闭流值之前刷新缓冲。
FileReader 类的对象可以调用父类中 read 方法从文件中读取字符
// 使用 FileReader 从文件中读取字符
class Demo {
public static void main (String[] args) throws IOException {
// 创建 FileReader 对象,从 1.txt 读取字符
FileReader fr = new FileReader("1.txt");
fr.read();//读取一个字符
fr.read();//继续读取一个字符,如果到达文件末尾,则返回 -1
char[] ch = new char[1024];
fr.read(ch);// 将字符读入字符数组
fr.read(ch,0,100);// 将字符读入字符数组的一部分,其中 0 为开始处,100 为要读取的最多字符数
}
}
(2)BufferedWriter 和 BufferedReader
通过将 FileWriter 或 FileReader 的对象传入 BufferedWriter 或 BufferedReader 的对象,可以提高读写操作的速度,此外,还可以使用这两个类中的特有方法。
// 从创建文件输入输出流并将其传入 BufferedWriter 和 BufferedReader 类的对象中
import java.io.*;
class Demo {
public static void main (String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("1.txt"));
// 创建 BufferedReader 对象,将 FileReader 对象传入 BufferedReader 对象中
String s = br.readLine();
// 从文件中读取一个文本行并返回一个字符串,如果到达文件末尾,则返回 null
BufferedWriter bw = new BufferedWriter (new FileWriter("2.txt"));
// 创建 BufferedWriter 对象,将 FileWriter 对象传入 BufferedWriter 对象中
bw.write(s);
bw.newLine();//写入一个行分割符,在 Windows 中为 '/r' 和 '/n' ,在 Linux 下为 '/n'
bw.close();
}
}
四、字节流
(1)FileInputStream 和 FileOutputStream
FileInputStream 和 FileOutputStream 类的对象用于从文件中读取字节流或向文件写入字节流,可用于非文本文件的读取和写入。
// 使用 FileInputStream 和 FileOutputStream 类的对象读取文件数据和将数据写入到文件
import java.io.*;
class Demo {
public static void main (String[] args) throws IOException {
// 创建 FileInputStream 对象
FileInputStream fis = new FileInputStream("1.bmp");
fis.read();//从文件中读取一个数据
byte[] b = new byte[1024];
fis.read(b,0,100);//将文件中的数据读取到字符数组中的一部分
fis.read(b);//将文件中的数据读取到 byte 数组中
// 创建 FileOutputStream 对象
FileOutputStream fos = new FileOutputStream("2.bmp");
fos.write(2);
//将一个字节写入文件,传入整型数据,取数据的最后一个字节写入文件
fos.write(b);//将 byte 数组中的数据写入文件
fos.write(b,0,100);//将 byte 数组中一部分的数据写入文件
}
}
(2)BufferedInputStream 和 BufferedOutputStream
BufferedInputStream 和 BufferedOutputStream 类的使用与 BufferedWriter 和 BufferedReader 类类似,可以传入 InputStream 和 OutputStream 类的对象,并可以起到加快读写操作速度的作用。
五、字符流和字节流的转换
通过 InputStreamReader 和 OutStreamWriter 类的对象可以将输入和输出的字节流转换为字符流。
//将键盘输入写入文件
import java.io.*;
class Demo {
public static void main (String[] args) throws IOException {
// 将键盘输入转换为字符流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 创建字符到文件的输出流
BufferedWriter fw = new BufferedWriter(new FileWriter("1.txt"));
//将键盘录入写入文件,输入 over 后停止录入
String s = null;
while(true) {
s = br.readLine();
if(s.equals("over"))
break;
fw.write(s);
fw.newLine();
fw.flush();
}
br.close();
fw.close();
}
}
// 使用 OutputStreamWriter 将屏幕输出转换为字符流
import java.io.*;
class Demo {
public static void main (String[] args) throws IOException {
//将屏幕输出转换为字符流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 创建输入字符流
BufferedReader br = new BufferedReader(new FileReader("1.txt"));
//将文件中的字符打印到屏幕上
String line = null;
while((line = br.readLine())!= null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
六、File 对象
Java 中的 File 类的对象可以储存文件和文件夹的绝对或相对路径和名称等信息,无论文件是否实际存在。
可以使用以下语句创建 File 对象。
File file = new File ("1.txt");//储存文件名称
File file = new File ("C:\\dir\\1.txt");//储存绝对路径和文件名称
File file = new File ("dir\\1.txt");//储存相对路径和文件名称
因为使用单个“\”会发生转义,因此需要在路径中需要使用“\”,创建文件对象后,可以直接将文件对象传入输入输出流中。文件对象可以调用的常用方法包括:
file.canExecute();//判断对象表示的文件是否可执行
file.createNewFile();//如果对象中的储存的文件不存在,则创建一个新文件
file.delete();//删除对象中储存的文件路径所表示的文件
file.exists();//判断文件是否存在
file.isDirectory;//判断对象储存的是否是文件夹
file.list();
//如果该对象储存的是文件夹,则返回该文件夹下所有的文件和目录的名称作为元素的字符串数组
file.listFiles();//如果该对象储存的是文件夹,则返回使用该文件夹下所有的文件和目录的名称创建的文件对象的数组
七、字符编码
在将字节转换为字符时,就涉及到字符的编码问题,Java 在处理字符流时会使用系统默认的字符集,在中文系统中,默认的字符集为 GBK,此外,包含的中文的字符集还包括 UTF-8 等,GBK 用两个字节表示一个汉字,而 UTF-8 使用三个字节,因此如果使用 GBK 对字符进行编码,而在解码时使用 UTF-8 字符集,就不能显示原有的内容,且经过 UTF-8 解码后的内容无法在使用 UTF-8 编码回原来的二进制数据。