File
File对象就表示一个路径,可以是文件的路径,也可以是文件夹的路径
这个路径可以是存在的,也允许是不存在的
常见的构造方法:
| 方法名称 | 说明 |
|---|---|
| public File(String pathname) | 根据文件路径创建文件对象 |
| public File(String parent, String child) | 根据父路径名字符串和子路径名字符串创建文件对象 |
| public File(File parent, String child) | 根据父路径对应文件对象和子路径名字符串创建文件对象 |
变成File对象的目的就是为了使用File里面的方法
注意:假设有一个文件的路径为C:\Users\alienware\Desktop\a.txt,则其父(级)路径为C:\Users\alienware\Desktop,子(级)路径为a.txt
常见的成员方法:
判断、获取:
| 方法名称 | 说明 |
|---|---|
| public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 |
| public boolean isFile() | 判断此路径名表示的File是否为文件 |
| public boolean exists() | 判断此路径名表示的File是否存在 |
| public long length() | 返回文件的大小(字节数量) |
| public String getAbsolutePath() | 返回文件的绝对路径 |
| public String getPath() | 返回定义文件时使用的路径 |
| public String getName() | 返回文件的名称,带后缀 |
| public long lastModified() | 返回文件的最后修改时间(时间毫秒值) |
length方法细节:
① 这个方法只能获取文件的大小,单位是字节。如果我们要求单位是M、G,可以不断的除以1024
② 这个方法无法获取文件夹的大小,如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在一起
getName方法细节:如果调用者是文件,会返回文件名和后缀名,如果调用者是文件夹,那么只会返回文件夹名
创建、删除:
| 方法名称 | 说明 |
|---|---|
| public boolean createNewFile() | 创建一个新的空的文件 |
| public boolean mkdir() | 创建单级文件夹 |
| public boolean mkdirs() | 创建多级文件夹 |
| public boolean delete() | 删除文件、空文件夹 |
createNewFile方法细节:
① 如果当前路径表示的文件是不存在的,则创建成功,方法返回true;如果当前路径表示的文件是存在的,则创建失败,方法返回false
② 如果父级路径不存在,那么方法会有异常IOException
③ 该方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件
mkdir方法细节:
① windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false
② mkdir方法只能创建单级文件夹,无法创建多级文件夹
mkdirs方法细节:既可以创建单级的,又可以创建多级的文件夹
delete方法细节:
① 如果删除的是文件,则直接删除,不走回收站
② 如果删除的是空文件夹,则直接删除,不走回收站
③ 如果删除的是有内容的文件夹,则删除失败
获取并遍历:
| 方法名称 | 说明 |
|---|---|
| public File[] listFiles() | 获取当前该路径下所有内容 |
listFiles方法细节:
① 当调用者File表示的路径不存在时,返回null
② 当调用者File表示的路径是文件时,返回null
③ 当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
④ 当调用者File表示的路径是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
⑤ 当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
⑥ 当调用者File表示的路径是需要权限才能访问的文件夹时,返回null
举例:
File f = new File("D:\\aaa");
//需求:打印里面所有的txt文件
File[] arr = f.listFiles();
for(File file : arr) {
//file依次表示aaa文件夹里面每一个文件或者文件夹的路径
if(file.isFile() && file.getName().endsWith(".txt")) {
System.out.println(file);
}
}
其他获取并遍历方法(了解):
| 方法名称 | 说明 |
|---|---|
| public static File[] listRoots() | 列出可用的文件系统根 |
| public String[] list() | 获取当前该路径下所有内容(只有文件名) |
| public String[] list(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
| public File[] listFiles(FileFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
| public File[] listFiles(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下所有内容 |
IO流的体系
IO流:存储和读取数据的解决方案,用于读写文件中的数据(可以读写文件,或网络中的数据…)
IO流的分类:

纯文本文件:用windows系统自带的记事本打开并且能读懂的文件
字节流体系:

字符流体系:

带高级流的体系:

字节流
FileOutputStream:
操作本地文件的字节输出流,可以把程序中的数据写到本地文件中
书写步骤:
① 创建字节输出流对象
② 写数据
③ 释放资源
举例:
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new
FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\a.txt");
//写出数据
fos.write(97); //实际是字符a
//释放资源
fos.close();
}
细节:
1.创建字节输出流对象
① 参数是字符串表示的路径或者File对象都是可以的
② 如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的,否则会报错
③ 如果文件已经存在,则会清空文件中的内容
2.写数据
write方法的参数是整数,但是实际上写到本地文件中的整数是在ASCII上对应的字符
3.释放资源
每次使用完流之后都要释放资源,否则资源会一直被程序占用
FileOutputStream写数据的3种方式:
| 方法名称 | 说明 |
|---|---|
| void write(int b) | 一次写一个字节数据 |
| void write(byte[] b) | 一次写一个字节数组数据 |
| void write(byte[] b, int off, int len) | 一次写一个字节数组的部分数据 |
**第三个方法细节:**第二个参数off表示的是起始索引,第三个参数表示要写数据的个数
换行写:
windows:\r\n(回车(将光标移动到这一行的最前面 )+ 换行(把光标移动到下一行))
Linux:\n
Mac:\r
细节:在windows操作系统当中,java对回车换行进行了优化,虽然完整的是\r\n,但是我们写其中一个\r或者\n,java也可以实现换行,因为java在底层会补全
续写:如果想要续写,打开续写开关即可。开关位置:创建对象的第二个参数append,默认为false,表示关闭续写,此时创建对象会清空文件。手动传递true表示打开续写,此时创建对象不会清空文件
举例:
//创建对象
FileOutputStream fos = new FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\a.txt", true); //true表示打开续写
//写出数据
String str = "aniyahaokeai";
byte[] bytes1 = str.getBytes();
fos.write(bytes1);
String wrap = "\r\n";
byte[] bytes2 = wrap.getBytes();
fos.write(bytes2);
String str2 = "666";
byte[] bytes3 = str2.getBytes();
fos.write(bytes3);
//释放资源
fos.close();
FileInputStream:
操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来
书写步骤:
① 创建字节输入流对象
② 读数据
③ 释放资源
举例:
public static void main(String[] args) throws IOException {
//创建对象
FileInputStream fis = new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\a.txt");
//读取数据
int b = fis.read();
System.out.println(b);
//释放资源
fis.close();
}
细节:
1.创建字节输入流对象
如果文件不存在,就直接报错
2.读取数据
① 一次读一个字节,读出来的是数据在ASCII上对应的数字
② 读到文件末尾了,read方法返回-1
3.释放资源
每次使用完流必须要释放资源
循环读取:
public static void main(String[] args) throws IOException {
//创建对象
FileInputStream fis = new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\a.txt");
//读取数据
int b;
while((b = fis.read()) != -1) {
System.out.println((char)b);
}
//释放资源
fis.close();
}
练习:文件拷贝
//创建对象
FileInputStream fis = new FileInputStream("D\\itheima\\movie.mp4");
FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");
//拷贝
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
//释放资源
//规则:先开的最后关闭
fos.close();
fis.close();
弊端:一次读写一个字节,速度太慢
FileInputStream一次读多个字节:
| 方法名称 | 说明 |
|---|---|
| public int read() | 一次读一个字节数据 |
| public int read(byte[] buffer) | 一次读一个字节数组数据 |
注意:
① 一次读一个字节数组的数据,每次读取会尽可能把数组装满,数组的长度建议是1024的整数倍。
② 方法返回值是读取到的字节数据个数,若没有读取到数据,则会返回-1
③ 读取到的数据会存放在bytes数组中,如果数组原来有值,会进行覆盖。若读取的个数小于数组长度,只会覆盖前面等数量的数据,而后面的数据会被保留
文件拷贝改写:
FileInputStream fis = new FileInputStream("D:\\itheima\\movie.mp4");
FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
try…catch异常处理:
try {
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(97);
} catch(IOException e) {
e.printStackTrace();
} finally { //被finally控制的语句一定会执行,除非JVM退出(例如System.exit(0))
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
接口AutoCloseable:
特点:特定的情况下,可以自动释放资源
在实现了接口AutoCloseable的类的条件下,可以有以下方式自动释放资源实现类的对象:

字符集
ASCII:
ASCII编码规则:前面补0,补其8位(总共只有128个字符,占7位)
ASCII解码规则:直接转成十进制
简体中文版windows系统默认使用的是GBK,而系统显示的是ANSI
GBK:
英文:要求:英文用一个字节存储,完全兼容ASCII
汉字:
规则1:汉字用两个字节来存储
规则2:高位字节二进制一定以1开头,转成十进制之后是一个负数(目的是为了与英文的0开头区分)
**GBK汉字编码规则:**不需要变动
**GBK汉字解码规则:**直接将二进制转换成十进制,然后查询GBK
Unicode:
UTF-16编码规则:用2~4个字节保存
UTF-32编码规则:固定使用四个字节保存
UTF-8编码规则:用1~4个字节保存(重点)

英文:和ASCII一样
简体中文:3个字节,并且第一个字节的首位是1(实际就是把中文在unicode字符集里查询到的两个字节填入utf-8编码规则中,最终得到3个字节)
出现乱码的原因:
① 读取数据时未读完整个汉字(字节流一次读取一个字节)
② 编码和解码时的方式不统一
如何不产生乱码:
① 不要用字节流读取文本文件
② 编码解码时使用同一个码表,同一个编码方式
Java中编码的方法:
| String类中的方法 | 说明 |
|---|---|
| public byte[] getBytes() | 使用默认方式进行编码 |
| public byte[] getBytes(String charsetName) | 使用指定方式进行编码 |
Java中解码的方法:
| String类中的方法 | 说明 |
|---|---|
| String(byte[] bytes) | 使用默认方式进行解码 |
| String(byte[] bytes, String charsetName) | 使用指定方式进行解码 |
字符流
字符流的底层其实就是字节流(字符流 = 字节流 + 字符集)
特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节(具体读的字节数与字符集有关)
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
使用场景:对于纯文本文件进行读写操作
字符输入流FileReader:
书写步骤:
① 创建字符输入流对象
| 构造方法 | 说明 |
|---|---|
| public FileReader(File file) | 创建字符输入流关联本地文件 |
| public FileReader(String pathname) | 创建字符输入流关联本地文件 |
细节:如果文件不存在,就直接报错
② 读取数据
| 成员方法 | 说明 |
|---|---|
| public int read() | 读取数据,读到末尾返回-1 |
| public int read(char[] buffer) | 读取多个数据,读到末尾返回-1 |
read()细节:
① 按字节进行读取,遇到中文,一次读多个字节,读取后解码,返回一个整数。若想看到这些字符,则需要进行强制类型转换
② 读到文件末尾,read方法返回-1
read(char[] buffer)细节:读取数据、解码、强制类型转换三步合并了,把强转之后的字符放到数组当中
③ 释放资源
| 成员方法 | 说明 |
|---|---|
| public int close() | 释放资源 / 关流 |
举例:
//1.创建文件并关联本地文件
FileReader fr = new FileReader("day27-code\\a.txt");
//2.读取数据 read()
int ch;
while((ch = fr.read()) != -1) {
System.out.print((char)ch);
}
//3.释放资源
fr.close();
//一次读取多个字符
FileReader fr = new FileReader("day27-code\\a.txt");
char[] chars = new char[2];
int len;
while((len = fr.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
fr.close();
字符输出流FileWriter:
构造方法:
| 构造方法 | 说明 |
|---|---|
| public FileWriter(File file) | 创建字符输出流关联本地文件 |
| public FileWriter(String pathname) | 创建字符输出流关联本地文件 |
| public FileWriter(File file, boolean append) | 创建字符输出流关联本地文件,续写 |
| public FileWriter(String pathname, boolean append) | 创建字符输出流关联本地文件,续写 |
成员方法:
| 成员方法 | 说明 |
|---|---|
| void write(int c) | 写出一个字符 |
| void write(String str) | 写出一个字符串 |
| void write(String str, int off, int len) | 写出一个字符串的一部分 |
| void write(char[] cbuf) | 写出一个字符数组 |
| void write(char[] cbuf, int off, int len) | 写出字符数组的一部分 |
书写步骤:
① 创建字符输出流对象
细节:
① 参数是字符串表示的路径或者File对象都是可以的
② 如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
③ 如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
② 写数据
细节:如果write方法的参数是整数,实际上写到本地文件中的是整数在字符集上对应的字符
③ 释放资源
细节:每次使用完流之后都要释放资源
字符流原理解析:
1.字符输入流
(1)创建字符输入流对象
底层:关联文件,并创建缓冲区(长度为8192的字节数组)。缓冲区的目的是为了防止多次从硬盘中读取数据而耗费时间
(2)读取数据
底层:
① 判断缓冲区中是否有数据可以读取
② 缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区;如果文件中没有数据了,返回-1
③ 缓冲区有数据:就从缓冲区中读取
2.字符输出流
在内存中同样会创建一个缓冲区(长度为8192的字节数组),遇到以下三种情况时才会把缓冲区的数据写入文件中:
① 缓冲区装满了
② 手动刷新(flush方法)
③ 释放资源(close方法)
flush和close方法:
| 成员方法 | 说明 |
|---|---|
| public void flush() | 将缓冲区中的数据,刷新到本地文件中 |
| public void close() | 释放资源 / 关流 |
flush刷新:刷新之后,还可以继续往文件中写出数据
close关流:断开通道,无法再往文件中写出数据
字节流和字符流的使用场景:
字节流:拷贝任意类型的文件
字符流:
① 读取纯文本文件中的数据
② 往纯文本文件中写出数据
缓冲流
1.字节缓冲流:
原理:底层自带了长度为8192的缓冲区提高性能(字节数组)
构造方法:
| 方法名称 | 说明 |
|---|---|
| public BufferedInputStream(InputStream is) | 把基本流包装成高级流,提高读取数据的性能 |
| public BufferedOutputStream(OutputStream os) | 把基本流包装成高级流,提高写出数据的性能 |
示例:
//1.创建缓冲流的对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\copy.txt"));
//2.循环读取并写到目的地
int b;
while((b = bis.read()) != -1) {
bos.write(b);
}
//3.释放资源
bos.close();
bis.close();
注意:关流的时候只用关缓冲流即可,因为底层会自动关闭基本流
字节缓冲流提高效率的原理:

2.字符缓冲流:
原理:底层自带了长度为8192的缓冲区提高性能(字符数组)
构造方法:
| 方法名称 | 说明 |
|---|---|
| public BufferedReader(Reader r) | 把基本流变成高级流 |
| public BufferedWriter(Writer r) | 把基本流变成高级流 |
特有方法:
| 字符缓冲输入流特有方法 | 说明 |
|---|---|
| public String readLine() | 读取一行数据,如果没有数据可读了,会返回null |
注意:readline方法不会把回车读到内存中
| 字符缓冲输出流特有方法 | 说明 |
|---|---|
| public void newLine() | 跨平台的换行 |
示例:
字符缓冲输入流:
//1.创建字符缓冲输入流的对象
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\HONOR\\Desktop\\test\\src\\a.txt"));
//2.读取数据
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
//3.释放资源
br.close();
字符缓冲输出流:
//1.创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\HONOR\\Desktop\\test\\src\\d.txt", true));
//2.写出数据
bw.write("好好好好好好");
bw.newLine();
bw.write("牛的");
//3.释放资源
bw.close();
缓冲流可以显著提高字节流的读写性能,对于字符流提升不明显(因为字符流的基本流中已经存在缓冲区),对于字符缓冲流而言关键点是两个特有的方法
IO流使用原则:随用随创建,什么时候不用什么时候关闭
转换流
转换流是字符流和字节流之间的桥梁,可以将字节流转换为字符流

作用:
① 指定字符集读写数据(JDK11之后已淘汰)
② 字节流想要使用字符流中的方法
字符转换输入流:InputStreamReader
字符转换输出流:OutputSreamWriter
示例:
作用1:
/*
//1.创建对象并指定字符编码
//了解,因为JDK11这种方法被淘汰了
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\编程代码\\java\\basic-code\\day28-code\\src\\test7\\gbkfile.txt"), "GBK");
//2.读取数据
int ch;
while((ch = isr.read()) != -1) {
System.out.print((char)ch);
}
//3.释放资源
isr.close();
*/
FileReader fr = new FileReader("D:\\编程代码\\java\\basic-code\\day28-code\\src\\test7\\gbkfile.txt", Charset.forName("GBK"));
int ch;
while((ch = fr.read()) != -1) {
System.out.print((char)ch);
}
fr.close();
/*
//1.创建转换流的对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\编程代码\\java\\basic-code\\day28-code\\src\\test8\\b.txt"), "GBK");
//2.写出数据
osw.write("你好");
//3.关闭资源
osw.close();
*/
FileWriter fw = new FileWriter("D:\\编程代码\\java\\basic-code\\day28-code\\src\\test8\\c.txt", Charset.forName("GBK"));
fw.write("你好");
fw.close();
作用2:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\d.txt")));
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
序列化流
序列化流(对象操作输出流):可以把java中的对象写到本地文件中
| 构造方法 | 说明 |
|---|---|
| public ObjectOutputStream(OutputStream out) | 把基本流包装成高级流 |
| 成员方法 | 说明 |
|---|---|
| public final void writeObject(Object obj) | 把对象序列化(写出)到文件中去 |
细节:使用对象输出流将对象保存到文件时会出现NotSerializableException异常
解决方案:需要让Javabean类实现Serializable接口(注意:Serializable接口里面是没有抽象方法的,是标记型接口,一旦实现了这个接口,那么就表示当前的类可以被序列化)
示例:
public class Student implements Serializable {
private String name;
private int age;
}
//1.创建对象
Student stu = new Student("zhangsan", 18);
//2.创建序列化流的对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\object.txt"));
//3.写出数据
oos.writeObject(stu);
//4.释放资源
oos.close();
反序列化流(对象操作输入流):
可以把序列化到本地文件中的对象,读取到程序中来
| 构造方法 | 说明 |
|---|---|
| public ObjectInputStream(InputStream out) | 把基本流变成高级流 |
| 成员方法 | 说明 |
|---|---|
| public Object readObject() | 把序列化到本地文件中的对象,读取到程序中来 |
示例:
//1.创建反序列化流的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\object.txt"));
//2.读取数据
Student o = (Student) ois.readObject();
//3.打印对象
System.out.println(o);
//4.释放资源
ois.close();
细节:
① 序列化对象后,修改了Javabean类,再次反序列化,会出现问题,会抛出InvalidClassException异常
如果先用序列化流将一个对象保存到文件中,然后再修改这个对象的类的结构,再用反序列化流读取文件中的对象,此时会报错。因为java底层会给类里所有的内容计算出一个序列号(版本号),对象中会包含版本号,文件中也会包含版本号信息。如果修改了类的结构,那么类的版本号会发生变化,进而导致用反序列化流读取对象时,版本号匹配失败,最后代码报错
解决方法:固定版本号
public class Student implements Serializable {
//注意:变量名是固定的,只能是serialVersionUID
private static final long serialVersionUID = -6446448739912835636L;
private String name;
private int age;
private String address;
}
② 序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来了
③ 如果一个对象中的某个成员变量的值不想被序列化,实现方法:给该成员变量加transient(瞬态关键字)关键字修饰,该关键字标记的成员变量不参与序列化过程,从文件读取过来的时候,该属性的值是默认初始化值
练习:
需求:将多个自定义对象序列化到文件中,但是对象的个数不确定
解决方法:使用ArrayList集合
public static void main(String[] args) throws IOException {
//序列化多个对象
Student s1 = new Student("zhangsan", 19, "深圳");
Student s2 = new Student("lisi", 24, "重庆");
Student s3 = new Student("wangwu", 25, "北京");
ArrayList<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\Object.txt"));
oos.writeObject(list);
oos.close();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建反序列化流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\Object.txt"));
//2.读取数据
ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
for (Student student : list) {
System.out.println(student);
}
//3.释放资源
ois.close();
}
打印流

分类:打印流一般是指:PrintStream,PrintWriter两个类
特点:
① 打印流只操作文件目的地,不操作数据源
② 特有的写出方法可以实现,数据原样写出(例如:打印97 文件中:97)
③ 特有的写出方法可以实现,自动刷新,自动换行(打印一次数据 = 写出 + 换行 + 刷新)
字节打印流:
| 构造方法 | 说明 |
|---|---|
| public PrintStream(OutputStream / File / String) | 关联字节输出流 / 文件 / 文件路径 |
| public PrintStream(String fileName, Charset charset) | 指定字符编码 |
| public PrintStream(OutputStream out, boolean autoFlush) | 自动刷新 |
| public PrintStream(OutputStream out, boolean autoFlush, String encoding) | 指定字符编码且自动刷新 |
注意:字节流底层没有缓冲区,开不开自动刷新都一样
| 成员方法 | 说明 |
|---|---|
| public void write(int b) | 常规方法:规则跟之前一样,将指定的字节写出 |
| public void println(Xxx xx) | **特有方法:**打印任何数据,自动换行 |
| public void print(Xxx xx) | **特有方法:**打印任意数据,不换行 |
| public void printf(String format, Object… args) | **特有方法:**带有占位符的打印语句,不换行 |
示例:
//1.创建字节打印流的对象
PrintStream ps = new PrintStream(new FileOutputStream("C:\\Users\\HONOR\\Desktop\\test\\src\\d.txt"), true, Charset.forName("utf-8"));
//2.写出数据
ps.println(97);
ps.print(true);
ps.println();
ps.printf("%s爱上了%s", "阿珍", "阿强");
//3.释放资源
ps.close();
字符打印流:
| 构造方法 | 说明 |
|---|---|
| public PrintWriter(Write / File / String) | 关联字节输出流 / 文件 / 文件路径 |
| public PrintWriter(String fileName, Charset charset) | 指定字符编码 |
| public PrintWriter(Write w, boolean autoFlush) | 自动刷新 |
| public PrintWriter(OutputStream out, boolean autoFlush, String encoding) | 指定字符编码且自动刷新 |
注意:字符流底层有缓冲区,想要自动刷新需要开启
| 成员方法 | 说明 |
|---|---|
| public void write(…) | 常规方法:规则跟之前一样,写出字节或者字符串 |
| public void println(Xxx xx) | **特有方法:**打印任意类型的数据,自动换行 |
| public void print(Xxx xx) | **特有方法:**打印任意类型的数据,不换行 |
| public void printf(String format, Object… args) | **特有方法:**带有占位符的打印语句,不换行 |
示例:
//1.创建字符打印流的对象
PrintWriter pw = new PrintWriter(new FileWriter("C:\\Users\\HONOR\\Desktop\\test\\src\\d.txt"), true);
//2.写出数据
pw.println(97);
pw.print(true);
pw.println();
pw.printf("%s爱上了%s", "阿珍", "阿强");
//3.释放资源
pw.close();
压缩流

压缩包里面的每一个文件实际上都是ZipEntry对象,解压的本质就是把每一个ZipEntry按照层级拷贝到本地另一个文件夹中
示例:解压一个压缩包
public static void main(String[] args) throws IOException {
//1.创建一个File表示要解压的压缩包
File src = new File("C:\\Users\\HONOR\\Desktop\\test\\src.zip");
//2.创建一个File表示解压的目的地
File dest = new File("C:\\Users\\HONOR\\Desktop\\test\\");
//调用方法
unzip(src, dest);
}
public static void unzip(File src, File dest) throws IOException {
//创建一个解压缩流用来读取压缩包中的数据
ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
//表示当前在压缩包中获取到的文件或者文件夹
ZipEntry entry;
while((entry = zip.getNextEntry()) != null) {
System.out.println(entry);
if(entry.isDirectory()) {
//文件夹:需要在目的地dest处创建一个同样的文件夹
File file = new File(dest, entry.toString());
file.mkdirs();
}
else {
//文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件中(按照层级目录进行存放)
FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString()));
int b;
while((b = zip.read()) != -1) {
//写到目的地
fos.write(b);
}
fos.close();
//表示在压缩包中的一个文件处理完毕了
zip.closeEntry();
}
}
zip.close();
}
压缩流:
压缩本质:把每一个(文件 / 文件夹)看成ZipEntry对象放到压缩包中
示例:压缩单个文件
public static void main(String[] args) throws IOException {
//1.创建File对象表示要压缩的文件
File src = new File("C:\\Users\\HONOR\\Desktop\\test\\a.txt");
//2.创建File对象表示压缩包的位置
File dest = new File("C:\\Users\\HONOR\\Desktop\\test");
//3.调用方法用来压缩
toZip(src, dest);
}
/*
* 作用:压缩
* 参数一;表示要压缩的文件
* 参数二:表示压缩包的位置
* */
public static void toZip(File src, File dest) throws IOException {
//1.创建压缩流关联压缩包
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest, "a.zip")));
//2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
ZipEntry entry = new ZipEntry("a.txt");
//3.把ZipEntry对象放到压缩包中
zos.putNextEntry(entry);
//4.把src文件中的数据写到压缩包当中
FileInputStream fis = new FileInputStream(src);
int b;
while((b = fis.read()) != -1) {
zos.write(b);
}
fis.close();
zos.closeEntry();
zos.close();
}
示例:压缩文件夹
public static void main(String[] args) throws IOException {
//1.创建File对象表示要压缩的文件夹
File src = new File("C:\\Users\\HONOR\\Desktop\\test\\src");
//2.创建File对象表示压缩包放在哪里(压缩包的父级路径)
File destParent = src.getParentFile();
//3.创建File对象表示压缩包的路径
File dest = new File(destParent, src.getName() + ".zip");
//4.创建压缩流关联压缩包
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
//5.获取src里面的每一个文件,变成ZipEntry对象,放入压缩包当中
toZip(src, zos, src.getName());
//6.释放资源
zos.close();
}
/*
* 作用:获取src里面的每一个文件,变成ZipEntry对象,放入压缩包当中
* 参数一:数据源
* 参数二:压缩流
* 参数三:压缩包内部的路径
* */
public static void toZip(File src, ZipOutputStream zos, String name) throws IOException {
//1.进入src文件夹
File[] files = src.listFiles();
//2.遍历数组
for (File file : files) {
if(file.isFile()) {
//3.判断-文件,变成ZipEntry对象,放入压缩包当中
ZipEntry entry = new ZipEntry(name + "\\" + file.getName());
zos.putNextEntry(entry);
FileInputStream fis = new FileInputStream(file);
int b;
while((b = fis.read()) != -1) {
zos.write(b);
}
fis.close();
zos.closeEntry();
}
else {
//4.判断-文件夹,递归
toZip(file, zos, name + "\\" + file.getName());
}
}
}
properties
配置文件的好处:
① 可以把软件的设置永久化存储
② 如果我们要修改参数,不需要改动代码,直接修改配置文件就可以了
properties配置文件的特点:
① 后缀名为properties
② 文件中所有的数据都是按照键值对的形式存储的
properties是一个双列集合的集合,拥有Map集合所有的特点
重点:有一些特有的方法,可以把集合中的数据,按照键值对的形式写到配置文件当中,也可以把配置文件中的数据,读取到集合中来
示例:
将集合写到文件中:
public static void main(String[] args) throws IOException {
/*
* Properties跟IO流结合的操作
* */
//1.创建集合
Properties prop = new Properties();
//2.添加数据
prop.put("aaa", "111");
prop.put("bbb", "222");
prop.put("ccc", "333");
prop.put("ddd", "444");
prop.put("eee", "555");
//3.把集合中的数据以键值对的形式写到本地文件中
FileOutputStream fos = new FileOutputStream("day29-code\\src\\test10\\a.properties");
prop.store(fos, "test"); //"test"为注释信息
fos.close();
}
运行结果:

将文件读到集合中
public static void main(String[] args) throws IOException {
//1.创建集合
Properties prop = new Properties();
//2.读取本地properties文件里面的数据
FileInputStream fis = new FileInputStream("day29-code\\src\\test10\\a.properties");
prop.load(fis);
fis.close();
//3.打印集合
System.out.println(prop);
}
件的特点:
① 后缀名为properties
② 文件中所有的数据都是按照键值对的形式存储的
properties是一个双列集合的集合,拥有Map集合所有的特点
重点:有一些特有的方法,可以把集合中的数据,按照键值对的形式写到配置文件当中,也可以把配置文件中的数据,读取到集合中来
示例:
将集合写到文件中:
public static void main(String[] args) throws IOException {
/*
* Properties跟IO流结合的操作
* */
//1.创建集合
Properties prop = new Properties();
//2.添加数据
prop.put("aaa", "111");
prop.put("bbb", "222");
prop.put("ccc", "333");
prop.put("ddd", "444");
prop.put("eee", "555");
//3.把集合中的数据以键值对的形式写到本地文件中
FileOutputStream fos = new FileOutputStream("day29-code\\src\\test10\\a.properties");
prop.store(fos, "test"); //"test"为注释信息
fos.close();
}
运行结果:

将文件读到集合中
public static void main(String[] args) throws IOException {
//1.创建集合
Properties prop = new Properties();
//2.读取本地properties文件里面的数据
FileInputStream fis = new FileInputStream("day29-code\\src\\test10\\a.properties");
prop.load(fis);
fis.close();
//3.打印集合
System.out.println(prop);
}
本文围绕Java的File和IO流展开。介绍了File对象表示路径及常用方法,阐述了IO流体系,包括字节流、字符流、缓冲流等。还讲解了字符集、转换流、序列化流、打印流、压缩流和properties配置文件的相关知识,如使用场景、操作步骤和注意事项。
1585

被折叠的 条评论
为什么被折叠?



