IO流是Java中处理输入输出的机制,也是访问数据源(如 文件、网络连接等)的方式。
1.IO流分类
Java的IO流分为字节流和字符流两种,字节流主要操作byte类型的数据,字符流主要操作char类型的数据。
字节流 | 字符流 | |
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
-
按照数据流的方向分为输入流和输出流:输入流用于从外部读取数据到程序中,输出流用于将程序中的数据输出到外部。
-
按照处理数据单位的不同,可以分为字节流和字符流:字节流以字节(8位)为单位进行数据读写,字符流以字符(16位)为单位进行数据读写,字符流是字节流的衍生物,字符流处理的是文本数据,可以自动进行字符集编码和解码,而字节流则主要处理二进制数据。
-
按照功能不同,可以分为节点流(低级流)和处理流(高级流):节点流可以直接读写文件、网络等数据源,是所有流的基础,而处理流则是对节点流的封装,增强了功能,可以实现对数据的缓冲、过滤、压缩、转换等操作,常用的处理流包括BufferedInputStream/BufferedOutputStream、ObjectInputStream/ObjectOutputStream、InputStreamReader/OutputStreamWriter等
绝对路径:指从文件系统的根目录开始一直到目标文件或目录的完整路径,以根目录为起点,包括完整的目录结构。
相对路径:指从当前工作目录开始,到目标文件或目录的路径。相对路径不包含文件系统根目录,而是从某个基准目录(通常是当前工作目录)开始计算。
Java IO流常用API | |
FileInputStream.read(byte[] b) | 从 FileInputStream 对象读取指定的字节数组中的数据 |
FileInputStream.read() | 从 FileInputStream 对象读取一个字节的数据 |
FileOutputStream.write(byte[] b) | 将指定的字节数组中的数据写入 FileOutputStream 对象 |
FileOutputStream.write(int b) | 将指定的字节写入 FileOutputStream 对象 |
BufferedInputStream.read(byte[] b, int off, int len) | 从 BufferedInputStream 对象读取指定长度的字节数组中的数据 |
BufferedOutputStream.write(byte[] b, int off, int len) | 将指定长度的字节数组中的数据写入 BufferedOutputStream 对象 |
FileReader.read(char[] cbuf, int off, int len) | 从 FileReader 对象读取指定长度的字符数组中的数据 |
FileWriter.write(char[] cbuf, int off, int len) | 将指定长度的字符数组中的数据写入 FileWriter 对象 |
BufferedReader.readLine() | 从 BufferedReader 对象读取一行文本数据 |
ObjectInputStream.readObject() | 从 ObjectInputStream 对象读取序列化的对象 |
ObjectOutputStream.writeObject() | 将指定的对象写入 ObjectOutputStream 对象进行序列化 |
2.File类
File类用于表示文件或目录的路径名。它提供了一系列方法来操作文件或目录,如创建、删除、重命名等。File类的实例可以代表一个文件、目录或者一个虚拟路径,独立于文件系统。
2.1.构造方法
File(File parent, String child) | 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 |
File(String pathname) | 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 |
File(String parent, String child) | 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 |
2.2.创建文件和目录
mkdir() | 创建单级目录 |
mkdirs() | 创建多级目录 |
在指定的目录下创建文件 |
2.3.删除文件或目录
delete() | 删除此抽象路径名表示的文件或目录。 |
2.4获取文件路径
获取绝对路径返回File类型 | |
getAbsolutePath() | 获取绝对路径返回String类型 |
getParent() | 获取当前文件的父路径 |
获取当前文件的父路径,返回一个File类型 | |
getPath() | 获取当前路径,返回一个String类型 |
getName() | 获取文件的名称和后缀 |
length() | 获取指定文件的总字节长度 |
2.5关于文件和目录的判断
exists() | 判断当前目录或者文件是否存在 |
判断当前抽象路径是否为目录 | |
isFile() | 判断当前抽象路径是否为文件 |
isHidden() | 判断当前抽象路径下的文件是否为隐藏文件 |
判断当前抽象路径是否为绝对路径 | |
canRead() | 判断当前抽象路径下的文件是否为只读文件 |
canWrite() | 判断当前抽象路径下的文件是否为只写文件 |
2.6获取子目录或子文件
list() | 获取指定目录下的所有子文件或者子目录的名称,返回字符串数组 |
获取指定目录下的所有子文件或者子目录绝对路径的File类型数组 | |
返回当前操作系统下所有盘符 |
File类的使用需要注意以下几点:
-
路径名的表示方法因操作系统而异,需要使用正确的路径分隔符。
-
文件操作涉及到文件系统的读写,可能会抛出IOException等异常。
-
File类不能操作文件内容的读写,需要使用InputStream、OutputStream等流类来完成。
import java.io.File;
public class Practice {
public static void main(String[] args) {
File f[] = new File[1]; //定义File类型数组方式
f[0] = new File("F:\\视频\\下载\\新建文件夹");
if(DelFile(f)) {
System.out.println("删除成功");
}
}
public static boolean DelFile(File f[]) { //递归删除文件
for(File i : f) {
if(i.isFile()) { //判断是否为文件
i.delete();
}
if(i.isDirectory()) { //判断是否为目录
DelFile(i.listFiles());
}
}
return true;
}
}
3.字符流
主要操作char类型的数据,操作的文件为文本类型的,视频图片之类的需要用字节流
3.1.字符输入和输出流
Reader(字符输入流):把文件中数据读入到程序中
read() | 读一个字符 |
read(char[] cbuf) | 将字符读入数组 |
read(char[] cbuf, int off, int len) | 将字符读入数组的一部分 |
Reader是一个抽象类不能实例化,调用他的子类FileReader
Writer(字符输出流):把程序中数据写入到文件中
write(char[] cbuf) | 写入一个字符数组 |
write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
write(int c) | 写一个字符 |
write(String str) | 写一个字符串 |
Writer是一个抽象类不能实例化,调用他的子类FileWriter
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) throws IOException {
FileReader file = new FileReader("F://视频/下载/新建文件夹/新建文本文档.txt");
int c = 0;
char a[] = new char[1024];
file.read(a);
FileWriter w = new FileWriter("w.txt");
w.write(a);
w.close(); //先关输出,再关输入
file.close();
}
}
3.2.字符缓冲输入流和输出流
默认有一个缓冲区,默认大小为8192,一次性可以读一行数据,提高读写效率
BufferedReader( 字符缓冲输入流)
readLine() | 一次性读一行文字 |
BufferedWriter( 字符缓冲输出流)
write() | 写一个字符串 |
newLine() | 写一个行分割符 |
4.字节流
主要操作byte类型的数据
4.1.字节输入和输出流
方法类似字符流;
InputStream(字节输入流)
InputStream是一个抽象类不能实例化,调用他的子类FileInputStream
OutputStream(字节输出流)
OutputStream是一个抽象类不能实例化,调用他的子类FileOutputStream
4.2字节缓冲输入流和输出流
提高读写效率,缓冲区最后如果不关闭流close或者刷新缓冲区fresh
BufferedInputStream( 字节缓冲输入流)
BufferedOutputStream( 字节缓冲输出流)
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class HomeWork {
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) throws IOException {
// 拷贝指定目录下的所有文件(不包含其子目录中的文件)到另一个目标目录中
// File old = new File("F:\\视频\\下载\\新建文件夹");
File fresh = new File("D:\\install\\WONIU-J-Install\\Eclipse IDE\\Day13");
File old = new File(scan.next());
long l1 = System.currentTimeMillis();
if(old.isDirectory()) {
File i[] = old.listFiles();
for(File j : i) {
if(j.isFile()) {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(j));
File f = new File(fresh, j.getName());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(f));
System.out.println(j);
System.out.println(j.getName());
byte arr[] = new byte[2048];
int a;
while((a= in.read(arr))!=-1) {
out.write(arr, 0, a);
}
out.close();
in.close();
}
}
System.out.println(System.currentTimeMillis()-l1);
}else {
try {
throw new RuntimeException();
} catch (RuntimeException e) {
System.out.println("输入的目录不合法");
}
}
}
}
8.对象流(ObjectInputStream和ObjectOutputStream)
实现将数据对象化永久存储
writeObject(Object o) | 将指定的对象写入ObjectOutputStream |
readObject() | 从ObjectInputStream读取一个对象。 |
7.转换流(InputStreamReader && OutputStreamWriter)
可以把字节输入和输出流转换成字符流进行读和写
8.合并流(SequenceInputStream)
把多个文件进行合并后并进行读取
9.行号流*(LineNumberReader)
行号流是指将文本文件中每一行的行号和内容一一对应形成的一个流,可以获取行号或设置行号。
10.内存流*(ByteArrayOutputStream和ByteArrayInputStream)
使用内存流可以在不使用文件的情况下进行数据的读写操作,常用于数据的缓存和传输过程中。内存流通常比磁盘流快,因为它们直接在内存中操作数据,而不需要进行磁盘I/O。但是,由于内存限制,内存流只能处理较小的数据量,通常用于处理临时数据和缓存数据。