Java基础 | IOStream

1.IO流概述

  1. IO流是用来处理设备之间的数据传输
  2. 对数组的操作是流方式
  3. 对于流的操作的类都在IO包中
  4. 按流分为输出类 输入流
  5. 按角色分为节点流 处理流
  6. 按数据类型分为字节流 字符流
  7. 流的异常需使用try catch finally处理

1.1流的体系图

IO体系结构

抽象基类实现类

2.字符流

  • 字符流主要用于处理纯文本文件
  • FileReader和FileWriter设计最常用的类

2.1FileReader

1
2
3
4
5
6
7
8
9
10
11
12
13
//1:提供File对象
File file = new File("a.txt");
//2:提供流对象对File操纵
FileReader fr= new FileReader(file);
//3.数据的读入
//read()返回读入的一个字符,如果达到文件末尾,返回-1
int data = fr.read();
while(data!=-1){
System.out.print((char)data);
data=fr.read();
}
//4.流的释放操作
fr.close();

2.2FileWriter

1
2
3
4
5
6
7
8
9
10
/*写入操作若文件不存在会默认把文件创建出来
若文件存在,构造器append参数为true就是追加
若为false就是覆盖原有数据*/

File file = new File("a.txt");
//append参数为true添加数据 为false覆盖原有数据
FileWriter fw =new FileWriter(file,true);
fw.write("zh:这是一个txt类型的文件\n");
fw.write("en:this is a file end with .txt\n");
fw.close();

3.字节流

  • 字节流主要用于处理非文本文件
  • 当只读取数据的时候字节流也可以处理文本文

3.1FileInputStream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//1.创建流对象获取文件
FileInputStream lyo = new FileInputStream("a.txt");

//2.读取数据
byte[] bt = new byte[5];
int len;
//循环判断如果读取的字节数据不为-1就执行
while ((len=lyo.read(bt)) != -1){
//输出为数组
/*for (int i = 0; i < len; i++) {
System.out.print(bt[i]+" ");
}*/
//输出为字符
String s = new String(bt, 0, len);
System.out.println(s);
}

//3.释放流
lyo.close();

3.2FileOutputStream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@IOAnnotation("字节流适用于除文本文件外文件的复制操作")
public static void unTestCopy(String beginPath,String endPath) throws IOException{
//1.创建流对象获取文件
FileInputStream pic = new FileInputStream(beginPath);
FileOutputStream cop = new FileOutputStream(endPath);

//2.读取数据(大型文件通常数组为1024个字节)
byte[] bt = new byte[1024];
int len;
while ((len = pic.read(bt)) != -1){
cop.write(bt,0,len);
}

//3.释放流
pic.close();
cop.close();
}

4.处理流

  1. 处理流就是在原本流的基础上增加功能
  2. 处理流也是装配设计模式在Java语言中的体现

4.1缓冲流

  1. 缓冲流的内部提供了一个缓冲区域
  2. 可以使得数据的读写传输速度更快
  3. 在流的体系图中带有Buffered的即为缓冲流

字节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void io_Copy() throws IOException {
//1.创建字符流包装到缓冲流中
FileInputStream origin = new FileInputStream("E:\\Videos\\滑板.mp4");
FileOutputStream after = new FileOutputStream("board.mp4");
BufferedInputStream bis = new BufferedInputStream(origin);
BufferedOutputStream bos = new BufferedOutputStream(after);

//2.数据的读写
byte[] bt = new byte[1024];
int len;
while ((len = bis.read(bt)) != -1){
bos.write(bt,0,len);
}

//3.释放流(只释放外层即可)
bis.close();
bos.close();
}

字符流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Test//
public void rw_Copy() throws IOException {
//1.创建字符流包装到缓冲流中
BufferedReader br =new BufferedReader(new FileReader("hello.txt"));
BufferedWriter bw =new BufferedWriter(new FileWriter("my.txt"));

//2.方式一 使用char数组
/*char[] cr = new char[5];
int len;
while ((len = br.read(cr)) != -1){
bw.write(cr,0,len);
bw.flush();//刷新缓冲区,后台会默认做无需手动实现
}*/

//2.方式二 使用String以及readLine方法
String num;
while ((num = br.readLine()) != null){
bw.write(num+"\n");
}

//3.释放流(只释放外层即可)
br.close();
bw.close();
}

4.2转换流

  1. 实现字节流与字符流之间的转换
  2. InputStreamReader 字节->字符 相当于解码的过程
  3. OutputStreamWriter 字符->字节 相当于编码的过程
    两者的转换图

解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//InputStreamReader把字节转换为字符
//1.获取流对象,添加进转换流中
FileInputStream files = new FileInputStream("hello.txt");
//可以指定字符格式为gbk,也可以不写即为默认
InputStreamReader isr = new InputStreamReader(files,"gbk");

//2.读取数据
int len;
char[] cr = new char[10];
while ((len = isr.read(cr)) != -1){
//通过String把数据通过控制台打印
String data = new String(cr, 0, len);
System.out.print(data);
}
//3.关闭流
isr.close();

编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//相当于编码操作
//1.创建转换流以及流对象 确定转换的字符集
FileInputStream origin = new FileInputStream("my.txt");
FileOutputStream after = new FileOutputStream("my_utf8.txt");
InputStreamReader gbk = new InputStreamReader(origin, "gbk");
OutputStreamWriter utf = new OutputStreamWriter(after, "utf-8");

//2.数据读写操作
int len;
char[] cr = new char[10];
while ((len = gbk.read(cr)) != -1){
utf.write(cr,0,len);
}

//3.关闭流
gbk.close();
utf.close();

4.3对象流

  1. 用于存储和读取基本数据类型或对象
  2. 可以把Java对象写入数据源中||从数据源恢复
  3. 对象流不能操纵被static和transient修饰的成员变量
  4. 反序列化ObjectInputStream
  5. 序列化ObjectOutputStream

自定义类序列化

  1. 实现serializable接口
  2. 提供serialVersionId常量
  3. 类中的所有属性也必须是序列化的

对文件的操纵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Test//序列化过程
public void OOS() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myText.dat"));

//添加对象到流文件中
oos.writeObject(new String("this is a secret file"));
oos.flush();
oos.writeObject(new ObjData(1,"banana",12.3));
oos.flush();

oos.close();
}

@Test//反序列化过程
public void OIS() throws Exception{

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myText.dat"));

//获取到数据强转为String输出
Object obj = ois.readObject();
String str = (String)obj;

//自定义类
ObjData oda = (ObjData)ois.readObject();

//获取到序列化文件中数据并输出
System.out.println(str);
System.out.println(oda);

ois.close();
}

4.4其他流

标准输入输出流

  • System.in 标准输入流
  • System.out 标准输出流

打印流

  • PrintStream PrintWriter
  • java最基本的输出语句就使用到了打印流

数据流

  • DataInputStream DataOutPutStream
  • 用于读取写出基本数据类型的变量或字符串

4.5 RAF

  • RandomAccessFile声明在IO中但直接继承Object
  • 即可作为输出流也可作为输入流
  • 实现了DataInput DataOutput接口
  • 创建以后需指定mode参数[r rw rwd rws]说明查看API
  • 作为输入流时会对原本文件内容进行从头覆盖
  • 若使用了seek( )则在指定光标位置插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//1.创建流对象,传入文件
File fl = new File("1.jpg");
File nfl = new File("2.jpg");
RandomAccessFile raf = new RandomAccessFile(fl,"r");
RandomAccessFile rag = new RandomAccessFile(nfl,"rw");

//2.读写
byte[] bytes = new byte[1024];
int len;
while ((len = raf.read(bytes)) != -1){
rag.write(bytes,0,len);
}
//3.释放流
raf.close();
rag.close();

//若需处理字符文件可以通过seek方法指定索引位置

5.File类

  1. 在java中对文件和文件目录路径的抽象表示形式
  2. File在这里应该理解为路径,文件路径或文件夹路径
  3. File类提供了对文件操作的基本方法,但没提供修改相关操作,需读写就需要使用IO流
  4. File类对象会作为参数传入IO流中

相对路径:指相较于某个路径下所指明的路径

绝对路径:指包含盘符的所有路径

5.1常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
createNewFile    创建指定类型文件
mkdir 创建文件夹
mkdirs 创建文件夹,若父类文件夹不存在,也会自动生成
File a = new File("Go.txt");
File b = new File("Java.txt");
//路径相同的情况下,进行换名,如果不同就是剪贴和改名
System.out.println(a.renameTo(b));
a.delete() 删除文件不走回收站

判断方法
isDirectory 判断是不是一个根目录
isFile 判断是不是一个文件
canRead 判断文件可不可读
canWrite 判断文件可不可写
isHidden 判断是不是隐藏文件

获取方法
String getAbsolutePath(); 获取绝对路径
String getPath(); 获取路径
String getName(); 获取名称
long length(); 获取长度字节数
long lastModified(); 获取最后一次修改时间,毫秒值
获取指定目录下的所有文件或文件夹的名称数组
String[] list();
获取指定目录下的所有文件或文件夹的File数组
File[] listFiles();

5.2构造器

根据一个路径得到File对象
File(String pathname):

根据一个目录和一个子文件/目录得到File对象
File(String parent,String child):

根据一个父file对象和一个子文件/目录得到File对象
File(File parent,String child):


Java基础 | IOStream
http://example.com/2022/06/05/Java初级部分/SEImprove/IOStream/
Author
John Doe
Posted on
June 5, 2022
Licensed under