IO流
I(Input 输入)/ O(Output 输出)流,是Java中用来传输数据的方式。
一、划分
按照流向:
- 输入流:从文件 读数据 到内存
- 输出流:从内存 写数据 到文件
按照操作:
- 字符流:以字符为单位操作数据
- Reader:字符输入流的顶层抽象类
- FileReader:普通的字符输入流
- BufferedReader:高效的字符输入流(字符缓冲输入流)
- Writer:字符输出流的顶层抽象类
- FileWriter:普通的字符输出流
- BufferedWriter:高效的字符输出流(字符缓冲输出流)
- Reader:字符输入流的顶层抽象类
- 字节流:以字节为单位操作数据
- InputStream:字节输入流的顶层抽象类
- FileInputStream:普通的字节输入流
- BufferedInputStream:高效的字节输入流(字节缓冲输入流)
- OutputStream:字节输出流的顶层抽象类
- FileOutputStream:普通的字节输出流
- BufferedOutputStream:高效的字节输出流(字节缓冲输出流)
- InputStream:字节输入流的顶层抽象类
二、File类
文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹
2.1 构造方法
- File(String pathname)
- File(String parent, String child)
- File(File parent, String child)
File file1 = new File("D:/abc/1.txt");
System.out.println("file1: " + file1);
File file2 = new File("D:/abc/", "1.txt");
System.out.println("file2: " + file2);
File file3 = new File("D:/abc/");
File file4 = new File(file3, "1.txt");
System.out.println("file4: " + file4);
2.2 成员方法
-
创建功能:如果不存在就创建,返回true;否则就不创建,返回false
- createNewFile():创建文件
- mkdir():创建单级目录
- mkdirs():创建目录
File file5 = new File("F:/abc/2.txt"); boolean flag1 = file5.createNewFile(); System.out.println("flag1: " + flag1); File file6 = new File("F:/a"); boolean flag2 = file6.mkdir(); System.out.println("flag2: " + flag2); File file7 = new File("F:/b/c"); boolean flag3 = file7.mkdirs(); // 也可以创建单级目录 System.out.println("flag3: " + flag3);
-
判断功能:
- isDirectory():判断File对象是否为目录
- isFile():判断File对象是否为文件
- exists():判断File对象是否存在
File file8 = new File("F:/a/b"); System.out.println("判断file8是否为文件夹:" + file8.isDirectory()); System.out.println("判断file8是否为文件:" + file8.isFile()); System.out.println("判断file8是否存在:" + file8.exists());
-
获取功能:
-
getAbsolutePath():获取绝对路径
绝对路径:以盘符开头的路径,例如D:/1.txt
-
getPath():获取文件的相对路径
相对路径:一般是相对于当前项目的路径而言,例如1.txt
-
getName():获取文件名
File file1 = new File("lib/3.txt"); file1.createNewFile(); String path1 = file1.getAbsolutePath(); System.out.println("绝对路径:" + path1); String path2 = file1.getPath(); System.out.println("相对路径:" + path2); String name = file1.getName(); System.out.println("文件名称:" + name);
- list():获取指定目录下所有文件(夹)的名称数组
- listFile():获取指定目录下所有文件(夹)的File数组
File file2 = new File("lib"); String[] names = file2.list(); System.out.println("lib目录下的文件(夹)名称如下:"); for (String s : names) { System.out.println(s); } File[] files = file2.listFiles(); System.out.println("lib目录下的文件(夹)数组如下:"); for (File file : files) { System.out.println(file); }
-
三、字符流
字符流只能拷贝纯文本文件!
3.1 字符输入流:Reader
- 创建字符输入流对象
FileReader
- 读取数据
- 释放资源
例子1:一次读取一个字符
public class ReaderDemo {
public static void main(String[] args) throws IOException {
// 1.创建字符输入流对象
Reader reader = new FileReader("lib/3.txt");
// 2.读取数据
/*
2.1 reader.read(),到文件中读取一个字符
2.2 ch = reader.read(),将读取到的字符赋值给变量ch
2.3 (ch = reader.read()) != -1,用读取到的字符(变量)和 -1 进行比较,若文件已经读完,会返回 -1
*/
int ch;
while ((ch = reader.read()) != -1) {
System.out.println(ch);
}
// 3.释放资源
reader.close();
}
}
例子2:一次读取一个字符数组
public class ReaderDemo {
public static void main(String[] args) throws IOException {
// 1.创建字符输入流对象
Reader reader = new FileReader("lib/3.txt");
// 2.读取数据
/*
2.1 reader.read(chs),到文件中读取若干字符到字符数组 chs中
2.2 len = reader.read(chs),将读取到的有效字符数量赋值给变量 len
2.3 (len = reader.read(chs)) != -1,用读取到的字符数量(变量)和 -1 进行比较,若文件已经读完,会返回 -1
*/
char[] chs = new char[3];
int len;
while ((len = reader.read(chs)) != -1) {
String s = new String(chs,0,len);
System.out.println(s);
}
// 3.释放资源
reader.close();
}
}
3.2 字符输出流:Writer
-
创建字符输出流对象
FileWriter
-
写入数据
void write(int ch); // 一次写一个字符
void write(char[] chs, int index, int len); //一次写一个字符数组
void write(String str); //一次写一个字符串
-
释放资源
public class WriterDemo {
public static void main(String[] args) throws IOException {
// 1.创建字符输出流对象
Writer writer = new FileWriter("lib/3.txt");
// 2.写入数据
// 2.1一次写入一个字符
writer.write("好");
// 2.2一次写入一个字符数组,起始 和 长度
char[] chars = {'华','南','农','业','大','学'};
writer.write(chars,1,2);
// 2.3一次写入一个字符串
writer.write("信息与计算科学");
// 3.释放资源
writer.close();
}
}
3.3 字符流拷贝:Reader + Writer
- 创建字符输入流对象,关联数据源文件
- 创建字符输出流对象,关联目的地文件
- 定义变量,用于记录读取到的内容
- 循环读取,将读取到的内容赋值给变量
- 将读取到的数据写入到 目的地文件中
- 释放资源
例子1:一次拷贝一个字符
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1. 创建字符输入流对象,关联数据源文件
FileReader fr = new FileReader("lib/1.txt");
// 2. 创建字符输出流对象,关联目的地文件
FileWriter fw = new FileWriter("lib/3.txt");
// 3. 定义变量,用于记录读取到的内容
int ch;
// 4. 循环读取,将读取到的内容赋值给变量
while ((ch = fr.read()) != -1) {
// 5. 将读取到的数据写入到 目的地文件中
fw.write(ch);
}
// 6. 释放资源
fr.close();
fw.close();
}
}
例子2:一次拷贝一个字符数组
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1. 创建字符输入流对象,关联数据源文件
FileReader fr = new FileReader("lib/1.txt");
// 2. 创建字符输出流对象,关联目的地文件
FileWriter fw = new FileWriter("lib/3.txt");
// 3. 定义变量,用于记录读取到的内容
char[] chs = new char[1024];
int len;
// 4. 循环读取,将读取到的内容赋值给变量,将读取到的有效字符数量赋值给变量 len
while ((len = fr.read(chs)) != -1) {
// 5. 将读取到的数据写入到 目的地文件中
fw.write(chs,0,len);
}
// 6. 释放资源
fr.close();
fw.close();
}
}
3.4 字符缓冲流拷贝
-
创建字符缓冲输入流对象,关联数据源文件
new BufferedReader(Reader reader);
-
创建字符缓冲输出流对象,关联目的地文件
new BufferedWriter(Writer writer);
字符缓冲流自带缓冲区,大小为8192个字符,即16KB
-
定义变量,用于记录读取到的内容
-
循环读取,将读取到的内容赋值给变量
-
将读取到的数据写入到 目的地文件中
-
释放资源
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1.创建字符缓冲输入流对象,关联数据源文件
FileReader fr = new FileReader("lib/1.txt");
BufferedReader br = new BufferedReader(fr);
// 2.创建字符缓冲输出流对象,关联目的地文件
FileWriter fw = new FileWriter("lib/3.txt");
BufferedWriter bw = new BufferedWriter(fw);
// 3.定义变量,用于记录读取到的内容
int len;
// 4.循环读取,将读取到的内容赋值给变量
while ((len = br.read()) != -1) {
// 5.将读取到的数据写入到 目的地文件中
bw.write(len);
}
// 6.释放资源
bw.close();
fw.close();
br.close();
fr.close();
}
}
一次读取写一行:
一次读取一行数据并返回读取到的内容,读不到就返回null
public String readLine(){};
根据当前操作系统给出对应的换行符
public void newLine(){};
操作系统 | 换行符 |
---|---|
windows | \r\n |
mac | \r |
unix | \n |
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1.创建字符缓冲输入流对象,关联数据源文件
BufferedReader br = new BufferedReader(new FileReader("lib/1.txt"));
// 2.创建字符缓冲输出流对象,关联目的地文件
BufferedWriter bw = new BufferedWriter(new FileWriter("lib/3.txt"));
// 3.定义变量,用于记录读取到的内容
String str;
// 4.循环读取,将读取到的内容赋值给变量
while ((str = br.readLine()) != null) {
// 5.将读取到的数据写入到 目的地文件中
bw.write(str);
// 注意换行
bw.newLine();
}
// 6.释放资源
bw.close();
br.close();
}
}
四、字节流
拷贝纯文本文件使用字符流,拷贝其他==(图片、音频、视频等)==使用字节流
4.1 字节流拷贝
InputStream + OutputStream
- 创建字节输入流对象
FileInputStream
,关联数据源文件 - 创建字节输出流对象
FileOutputStream
,关联目的地文件 - 定义变量,用于记录读取到的内容
- 循环读取,将读取到的内容赋值给变量
- 将读取到的数据写入到 目的地文件中
- 释放资源
例子1:一次拷贝一个字节
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1.创建字节输入流对象,关联数据源文件
FileInputStream fis = new FileInputStream("lib/a.jpg");
// 2.创建字节输出流对象,关联目的地文件
FileOutputStream fos = new FileOutputStream("lib/b.jpg");
// 3.定义变量,用于记录读取到的内容
int by;
// 4.循环读取,将读取到的内容赋值给变量
while ((by = fis.read()) != -1) {
// 5.将读取到的数据写入到 目的地文件中
fos.write(by);
}
// 6.释放资源
fos.close();
fis.close();
}
}
例子2:一次拷贝一个字节数组
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1.创建字节输入流对象,关联数据源文件
FileInputStream fis = new FileInputStream("lib/b.jpg");
// 2.创建字节输出流对象,关联目的地文件
FileOutputStream fos = new FileOutputStream("lib/c.jpg");
// 3.定义变量,用于记录读取到的内容
byte[] bys = new byte[2048];
int len;
// 4.循环读取,将读取到的内容赋值给变量,将读取到的有效字符数量赋值给变量 len
while ((len = fis.read(bys)) != -1) {
// 5.将读取到的数据写入到 目的地文件中
fos.write(bys,0,len);
}
// 6.释放资源
fos.close();
fis.close();
}
}
4.2 字节缓冲流拷贝
-
创建字节缓冲输入流对象,关联数据源文件
new BufferedInputStream(InputStream is);
-
创建字节缓冲输出流对象,关联目的地文件
new BufferedOutputStream(OutputStream os);
字节缓冲流自带缓冲区,大小为8192个字节,即8KB
-
定义变量,用于记录读取到的内容
-
循环读取,将读取到的内容赋值给变量
-
将读取到的数据写入到 目的地文件中
-
释放资源
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 1.创建字节缓冲输入流对象,关联数据源文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("lib/a.jpg"));
// 2.创建字节缓冲输出流对象,关联目的地文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lib/d.jpg"));
// 3.定义变量,用于记录读取到的内容
int len;
// 4.循环读取,将读取到的内容赋值给变量
while ((len = bis.read()) != -1) {
// 5.将读取到的数据写入到 目的地文件中
bos.write(len);
}
// 6.释放资源
bos.close();
bis.close();
}
}