I/O流

File类的使用

1、File类的一个对象,代表一个文件或一个文件目录
2、File类声明在java.io包下
File类对象常用方法:

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
32
33
34
35
36
37
@Test
public void test1() throws IOException {
File file1 = new File("src/IO/hello.txt");
// public String getAbsolutePath():获取绝对路径
System.out.println(file1.getAbsoluteFile());
// public String getPath() :获取路径
System.out.println(file1.getParent());
// public String getName() :获取名称
System.out.println(file1.getName());
// public String getParent():获取上层文件目录路径。若无,返回null
System.out.println(file1.getParent());
// public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
System.out.println(file1.length());
// public long lastModified() :获取最后一次的修改时间,毫秒值
// public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
// public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
//public boolean renameTo(File dest):把文件重命名为指定的文件路径
File file2 = new File("test.txt");
file1.renameTo(file2);
// public boolean isDirectory():判断是否是文件目录
// public boolean isFile() :判断是否是文件
// public boolean exists() :判断是否存在
// public boolean canRead() :判断是否可读
// public boolean canWrite() :判断是否可写
// public boolean isHidden() :判断是否隐藏
System.out.println(file2.exists());// true
System.out.println(file1.exists());// false

// public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
// public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
// public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建
// public boolean delete():删除文件或者文件夹
File file3 = new File("test1.txt");
file3.createNewFile();
file3.delete();

}

I/O流原理及流的分类

按操作的数据单位分为:字节流,字符流
按数据流向分为:输入流,输出流
四个抽象基类:
字节流:InputStream,OutputStream
字符流:Reader,Writer

按流的角色分为:节点流,处理流

节点流:
操作字节:FileInputStream,FileOutputStream
操作字符:FileReader,FileWriter
缓冲流(处理流的一种):
操作字节:BufferedInputStream,BufferedOutput
操作字符:BufferedReader,BufferedWriter

使用FileReader从硬盘中读取字符数据

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@Test
public void test1() {
FileReader fileReader = null;
try {
// 1.实例化File类对象
File file1 = new File("test.txt");// 相对于当前Modul
// 2.提供具体的流
fileReader = new FileReader(file1);
// 3.读数据
// read()返回读入的一个字符的ASCII码,如果到达末尾则返回-1
int data;
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {// 防止内存泄漏,必须关闭流
// 4.关闭流
try {
if (fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

@Test // 调用read(char[] cbuf) 返回每次读入cbuf数组中的字符个数,到达文件末尾返回-1
public void test2() throws IOException {
FileReader fr = null;
try {
File file1 = new File("test.txt");
fr = new FileReader(file1);
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf)) != -1) {
// for (int i = 0; i < cbuf.length; i++) {
// System.out.print(cbuf[i]);
// }

/*方式一:
for(int i=0;i<len;i++){
System.out.print(cbuf[i]);
}*/

// 方式二:
String str = new String(cbuf,0,len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null) {
fr.close();
}
}
}

使用FileWriter向硬盘中写入字符数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* 文件不存在则自动创建;
* new FileWriter(file1,false); 写入时将原来文件的内容覆盖(默认为false)
* new FileWriter(file1,true); 写入时追加到原文件内容后面
*/
@Test // 利用输入流向硬盘中写入数据
public void test3() throws IOException {
FileWriter fw = null;
try {
// 1.提供File类的对象,指明要写入的文件
File file1 = new File("test.txt");
// 提供FileWriter对象,用于数据写入
fw = new FileWriter(file1,true);
fw.write("哈哈哈哈哈,");
fw.write("歪比巴卜");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fw!=null){
fw.close();
}
}
}

使用FileInputStream,FileOutputStream对字节文件的处理

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
32
33
@Test
public void test1() throws IOException {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
File file1 = new File("pic.png");
File file2 = new File("pic1.png");
fi = new FileInputStream(file1);
fo = new FileOutputStream(file2);
byte[] pic = new byte[10];
int len;// 获取读取的字符长度
while((len = fi.read(pic))!=-1){
fo.write(pic,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fo!=null){
fo.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fi!=null){
fi.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

缓冲流的使用

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
32
33
34
35
36
37
38
39
 @Test // 内部通过提供一个缓冲区,提高文件的读取,写入速度
public void test1(){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
// 1.造文件
File file1 = new File("pic.png");
File file2 = new File("pic2.png");
// 2.造流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
// 3.造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
// 4.读取和写入
byte[] buff = new byte[5];
int len;
while((len = bis.read(buff))!=-1){
bos.write(buff,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bis!=null){
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bos!=null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

转换流

InputStreamReader:将IntputStream转换为Reader

OutputStreamWriter:将Writer转化为OutputStream

对象流

序列化:使用ObjectOutputStream类保存基本数据类型数据或对象
反序列化:使用ObjectInputStream类读取基本数据类型数据或对象
对象的序列化:允许把内存中的java对象转化为与平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或是通过网络节点将这种二进制流传输到另一个网络节点。当程序获取到这种二进制流后,可以恢复成原来的java对象。
对象的序列化与反序列化:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@Test  //序列化
public void test1(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("test.dat"));
oos.writeObject(new String("哈哈哈哈哈哈哈哈哈"));
oos.flush();
oos.writeObject(new Person("马老师",40));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(oos!=null){
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test2(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("test.dat"));
Object o = ois.readObject();
String str = (String) o;
System.out.println(str);// 哈哈哈哈哈哈哈哈哈
Person p = (Person) ois.readObject();
System.out.println(p);// Person{name='马老师', age=40}

} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
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
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* @author zyz
* @description 1、序列化对象需要实现Serializable接口
* 2、需要提供一个静态的全局常量serialVersionUID
* 3、保证当前类的所有属性是可序列化的
* @create 2020-03-12 15:47
*/
public class Person implements Serializable {
private String name;
private int age;
public static final long serialVersionUID = 42256165416L;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}