什么是流
-
概念:内存与存储设备之间传输数据的通道。 流的分类
-
按方向【重点】:
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
(文件 →[输入流]→ 程序 →[输出流]→ 文件)
-
按单位:
- 字节流:以字节为单位,可以读写所有数据 。
- 字符流:以字符为单位,只能读写文本数据 。
-
按功能:
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
字节流
-
字节流的父类(抽象类):
-
InputStream:字节输入流
- public int read() {}
- public int read(byte[] b) {}
- public int read(byte[] b, int off, int len) {}
-
OutputStream:字节输出流
- public void write(int n) {}
- public void write(byte[] b) {}
- public void write(byte[] b, int off, int len) {}
-
package com.zhang.IO流;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("d:\aaa.txt");
int data=0;
// while ((data=fileInputStream.read())!=-1){
// System.out.println((char) data);
// }
//一次读取多个字节
byte[] bytes = new byte[3];
int i=0;
while((i=fileInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,i));
}
fileInputStream.close();
}
}
D:\develop-tools\JDK\jdk-17.0.2\bin\java.exe "-javaagent:D:\develop-tools\IDEA\IntelliJ IDEA 2025.1.1.1\lib\idea_rt.jar=65093" -Dfile.encoding=UTF-8 -classpath D:\code\JAVA\IDEA\study1\out\production\study1;D:\code\JAVA\IDEA\study1\src\com\lib\commons-io-2.21.0.jar com.zhang.IO流.TestFileInputStream
abc
def
g
Process finished with exit code 0
public class TestFileOutputStream {
public static void main(String[] args) throws IOException {
//创建一个文件输出流,true表示激活追加写,就不会一个进程覆盖掉上一个进程写的了
FileOutputStream fileOutputStream = new FileOutputStream("d:\bbb.txt",true);
// fileOutputStream.write(97);
// fileOutputStream.write('b');
// fileOutputStream.write('c');
String str = " Hello World";
fileOutputStream.write(str.getBytes());
fileOutputStream.close();
}
}
IO流复制文件
public class TestFileOutputStream02 {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("D:\图片\Screenshots\屏幕截图(50).png");
FileOutputStream fileOutputStream = new FileOutputStream("D:\图片\Screenshots\copy.png");
/*
* buffer 是一个缓冲区,因为不知道要读的文件多大,所以
* 一次次填满缓冲区来循环读。以免发生内存溢出的问题
* len用来记录实际读取了多长的数据,以免最后不满缓冲区时读到上次循环未覆盖的数据
* 输入流读完会返回-1,以此判断是不是读完了
*/
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
}
}
字节缓冲流
-
缓冲流:BufferedInputStream/BufferedOutputStream
- 提高IO效率,减少访问磁盘的次数;
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
字节缓冲流内部就有一个缓冲区(buffer),和你自己定义的
byte[]本质上作用一样,但有优化。
-
小文件、简单场景:自己定义
byte[1024]就够用。 -
大文件、性能要求高:用缓冲流,省心又高效。
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("file.txt"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("copy.txt"))) {
int data;
while ((data = bis.read()) != -1) { // 内部用8KB缓冲区自动优化
bos.write(data);
}
}
```
public class TestBufferStream {
public static void main(String[] args) throws Exception {
FileInputStream inputStream = new FileInputStream("d:\aaa.txt");
FileOutputStream outputStream = new FileOutputStream("d:\bbb.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
int count = 0;
while ((count=bufferedInputStream.read())!=-1){
System.out.println((char) count);
}
bufferedInputStream.close();
for (int i = 0; i < 10; i++) {
bufferedOutputStream.write("hello world\r\n".getBytes());//\r是回车,\r\n在连在一块写主要是因为 Windows 系统中的换行符由这两个字符组成。
bufferedOutputStream.flush();//由于你一次写入的文件没有8k,故而只是写入了缓冲区,
// 达到8k前不会写入文件,使用flush就可以直接写入
}
bufferedOutputStream.close();
}
}
```
对象流
-
对象流:
ObjectOutputStream/ObjectInputStream-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能:
readObject()从流中读取一个对象writeObject(Object obj)向流中写入一个对象
-
使用流传输对象的过程称为序列化、反序列化。
package com.zhang.IO流;
import java.io.*;
public class TestObjectStream {
public static void main(String[] args) throws Exception {
// ObjectOutputStream objectOutputStream =//.bin是二进制文件的意思
// new ObjectOutputStream(new FileOutputStream("d:\abject.bin") );
ObjectInputStream objectInputStream =
new ObjectInputStream(new FileInputStream("d:\abject.bin"));
// TestObject a=new TestObject("zhnag");
// objectOutputStream.writeObject(a);//序列化文件
// objectOutputStream.close();//close自带flush功能
// System.out.println("序列化完毕");
TestObject b=(TestObject)objectInputStream.readObject();//反序列化文件
System.out.println("反序列化完毕");
System.out.println(b);
objectInputStream.close();
}
}
class TestObject implements Serializable {
//Serializable表示可序列化,必须实现这个接口
/*
如果有Student a;这种对象属性,那么这个属性的类也要实现Serializable
用transit修饰的属性不能被序列化,只会是默认值
静态属性不能被序列化
序列化多个类可以依靠集合实现
*/
private String name;
public TestObject(String name) {
this.name = name;
}
public TestObject() {
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
public String toString() {
return "TestObject{name = " + name + "}";
}
}
字符编码
- ISO-8859-1 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
- UTF-8 针对Unicode码表的可变长度字符编码
- GB2312 简体中文
- GBK 简体中文、扩充
- BIG5 台湾,繁体中文
文件字符流
-
FileReader:
public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。
-
FileWriter:
-
public void write(String str)//一次写多个字符,将b数组中所有字符,写入输出流。只能处理字符文件,不能实现上面的复制图片操作
-
public class TestFileReader {
public static void main(String[] args) throws Exception {
FileReader fileReader = new FileReader("d:\hello.txt");
FileInputStream fileInputStream = new FileInputStream("d:\hello.txt");
int count = 0;
int count2=0;
while ((count = fileReader.read()) != -1) {
System.out.print((char) count);
}
System.out.println();
/*
reader和writer可以依据默认的字符码读取写入文件,避免了出现乱码
*/
while ((count2=fileInputStream.read() )!= -1) {
System.out.print((char) count2);
}
fileReader.close();
fileInputStream.close();
}
}
D:\develop-tools\JDK\jdk-17.0.2\bin\java.exe "-javaagent:D:\develop-tools\IDEA\IntelliJ IDEA 2025.1.1.1\lib\idea_rt.jar=56141" -Dfile.encoding=UTF-8 -classpath D:\code\JAVA\IDEA\study1\out\production\study1;D:\code\JAVA\IDEA\study1\src\com\lib\commons-io-2.21.0.jar com.zhang.IO流.TestFileReader
好好学习
好好å¦ä¹
Process finished with exit code 0
字符缓冲流
- 缓冲流:BufferedReader/BufferedWriter
- 高效读写
- 支持输入换行符。
- 可一次写一行、读一行。
打印流
-
PrintWriter:
- 封装了print() / println()方法,支持写入后换行。
- 支持数据原样打印
public class TestPrintWriter {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter("d:\print.txt");
pw.println(97);
pw.println(true);
pw.println(3.14);
pw.print('a');
pw.print('b');
pw.close();
}
}
转换流
-
桥转换流:InputStreamReader/OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
File类
-
概念:代表物理盘符中的一个文件或者文件夹。
-
方法:
- createNewFile()//创建一个新文件
- mkdir()//创建一个新目录
- delete()//删除文件或空目录
- exists()//判断File对象所代表的对象是否存在
- getAbsolutePath()//获取文件的绝对路径
- getName()//取得名字
- getParent()//获取文件/目录所在的目录
- isDirectory()//是否是目录
- isFile()//是否是文件
- length()//获得文件的长度
- listFiles()//列出目录中的所有内容
- renameTo()//修改文件名为
FileFilter接口
-
public interface FileFilter
- boolean accept(File pathname)
-
当调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。
、
补充:Properties
-
Properties:属性集合
-
特点
- 1 存储属性名和属性值
- 2 属性名和属性值都是字符串类型
- 3 没有泛型
- 4 和流有关