IO流:
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
input output stream:输入输出流
数据的流动:
- 狭义:数据在内存中输入和输出
- 常见:本地进程间的数据流动
- 广义:不同电脑之间的数据流动
- 常见:远程进程间的数据流动
IO流的分类:面向对象的思想
流的流动方向:数据的传输方向
输入流:cpu- >磁盘
输出流:磁盘->cpu
流的数据格式:
字节流
字符流:一个符号一个符号的读
流的主要作用:
节点流
装饰流(过滤流)
转换字节和字符流动的特殊流
转换流
拷贝文件:
@Test
void test06() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("c:\\a.jpg"));
bos = new BufferedOutputStream(new FileOutputStream(new File("c:\\b.jpg")));
byte[] buf = new byte[1024];
int len = 0;
while ((len = bis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
// 当代码执行到这儿的时候,读取完成
// 如果最后一次数据没有读取完成,则可以手动刷新缓冲区
// bos.flush();
System.out.println("文件拷贝成功!!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 缓存流,必须要关闭,因为JVM在缓存流关闭时,将最后数据完成自动刷新
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
jdk1.4--------->NIO
File对象
Java封装的一个操作文件及文件夹的对象
创建File对象
@Test
void test01() {
InputStream is = null;
try {
// 1、创建一个输入流对象(XXX数据流)
is = new FileInputStream("a.txt");
// 创建字节数组,通过字节数组读取数据
byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) != -1) {
System.out.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 一定要注意:流必须关闭
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
两个反斜杠表示一个反斜杠
绝对路径和相对路径:
绝对路径:直接可以定义文件的
window系统:直接使用盘符找:D:/a/b/c.jpg
相对路径:
过滤特定文件
遍历盘符
@Test
void test02() {
Reader reader = null;
Writer writer = null;
try {
reader = new FileReader(new File("I:\\java\\java_se\\2022\\day23\\src\\com\\openlab\\day23\\TestIO.java"));
writer = new FileWriter("c:\\a.java");
char[] buf = new char[1024];
int len = 0;
while((len = reader.read(buf)) != -1) {
writer.write(buf, 0, len);
}
System.out.println("拷贝文件成功");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
IO流必须关闭!!
如果出现多次,会读不尽,所以要用len
除非复制的数据是1024的整数倍
字节流:
输入流
输出流
装饰流:
又被称为过滤流,这种流不能直接使用,主要作用是用来装饰节点流
本质上是一种装饰者的设计模式体现,对原有对象的功能进一步增强。作用是加快流的传输效率
@Test
void test03() {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File("I:\\java\\java_se\\2022\\day23\\src\\com\\openlab\\day23\\TestIO.java")));
String msg = null;
// 字符输入流,可以使用装饰流,按行读取
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
GOF 23 中设计模式:
DateOutputStream:数据流
CAS(Compare and Swap):比较并且交换
字节流是最核心的
字符流:(主要为了加块流的操作,专门用来操像作字符串的流)
计算机底层使用的是二进制数据(字节数据)
注意:字符流存在编码问题,需要在读取和写入时保持一致
字符输入流:
字符输出流:
Write
字符装饰流
BufferedReader
BufferedWriter
PrintWriter 更推荐使用这个,因为会自动换行
打印输出流PrintWriter()
out.write改成out.println
转换流:
将字节流转换为字符流操作