喵星之旅-成长的雏鹰-java高级特性-3-io流

Alt text

file

什么是文件?
相关记录或放在一起的数据的集合。
文件一般存储在文件夹中。

Java程序如何访问文件属性?
JAVA API :java.io.File 类。该类型对象可操作文件和文件夹,是两种类型的统称。

1
File file = new File( String pathname );
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
import  java.io.*;
public class FileMethods {
public static void main(String[] args) {
FileMethods fm=new FileMethods();
File file=new File("D:\\myDoc\\test.txt");
//fm.create(file);
fm.showFileInfo(file);
//fm.delete(file);
}
/**
* 创建文件的方法
* @param file 文件对象
*/
public void create(File file){
if(!file.exists()){
try {
file.createNewFile();
System.out.println("文件已创建!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件
* @param file 文件对象
*/
public void delete(File file){
if(file.exists()){
file.delete();
System.out.println("文件已删除!");
}
}

/**
* 显示文件信息
* @param file 文件对象
*/
public void showFileInfo(File file){
if(file.exists()){ //判断文件是否存在
if(file.isFile()){ //如果是文件
System.out.println("名称:" + file .getName());
System.out.println("相对路径: " + file.getPath());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("文件大小:" + file.length()+ " 字节");
}
if(file.isDirectory()){
System.out.println("此文件是目录");
}
}else
System.out.println("文件不存在");
}
}

IO流

通过流来读写文件,流是一组有序的数据序列,以先进先出方式发送信息的通道。

按照流的方向进行分类

以内存作为参照物:
往内存中去:叫做输入(Input)。或者叫做读(Read)。
从内存中出来:叫做输出(Output)。或者叫做写(Write)。

按照读取数据方式不同进行分类

按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件等。

按照字符的方式读取数据的,一次读取一个字符.
这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。

纯文本文件,不单单是.txt文件,还包括 .java、.ini、.py 。总之只要 能用记事本打开 的文件都是普通文本文件。

IO流四大家族首领

字节流
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
字符流
java.io.Reader 字符输入流
java.io.Writer 字符输出流

注意:

1
2
3
4
5
6
7
四大家族的首领都是抽象类。(abstract class)
所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有 close() 方法。
流是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
所有的 输出流 都实现了:java.io.Flushable接口,都是可刷新的,都有 flush() 方法。
养成一个好习惯,输出流在最终输出之后,一定要记得flush()刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道。
ps:如果没有flush()可能会导致丢失数据。
在java中只要“类名”以 Stream 结尾的都是字节流。以“ Reader/Writer ”结尾的都是字符流。

字节流

java.io.FileInputStream

文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。

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
import java.io.*;

public class FileInputStreamTest {
public static void main(String[] args){
FileInputStream fis=null;
//创建流对象
try {
fis=new FileInputStream("d:\\myDoc\\hello.txt");
int data;
System.out.println("可读取的字节数:"+fis.available());
System.out.print("文件内容为:");
//循环读数据 read()方法是从输入流读取1个8位的字节,把它转化为0-255之间的整数返回。将返回的整数转换为字符
while((data=fis.read())!=-1){
System.out.print((char)data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//关闭流对象
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

java.io.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
import java.io.*;

public class FileOutputStreamTest {
public static void main(String[] args){
FileOutputStream fos=null;
try {
fos=new FileOutputStream("d:\\myDoc\\hello.txt",true);
String str="好好学习Java";
byte[] words=str.getBytes();
fos.write(words,0,words.length);
System.out.println("hello文件已更新");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("文件更新时出错!");
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.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
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class InputAndOutputFile {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//1、创建输入流对,负责读取D:/ 我的青春谁做主.txt文件
fis = new FileInputStream("D:/我的青春谁做主.txt");
//2、创建输出流对象
fos = new FileOutputStream("C:/myFile/myPrime.txt",true);
//3、创建中转站数组,存放每次读取的内容
byte[] words=new byte[1024];
//4、通过循环实现文件读取
int len = -1;
while((len = fis.read(words))!=-1){
fos.write(words, 0, len);
}
fos.flush();
System.out.println("复制完成,请查看文件!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//5、关闭流
try {
if(fos!=null)
fos.close();
if(fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}

}
}
}

字符流

BufferedReader

BufferedReader类是Reader类的子类
BufferedReader类带有缓冲区
按行读取内容的readLine()方法

1
2
FileReader fr = new FileReader("c:\\myDoc\\hello.txt");
BufferedReader br=new BufferedReader(fr);

解决读取时中文乱码

1
2
3
4
5
FileInputStream fis=new FileInputStream("c:\\myDoc\\hello.txt");
//使用InputStreamReader并设置编码格式
InputStreamReader fr=new InputStreamReader(fis,"UTF-8");
BufferedReader br=new BufferedReader(fr);

相对完整的实现

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
import java.io.*;

/*
* 当hello.txt编码格式是ANSI时,程序可以正常读取数据,(InputStreamReader fr=new InputStreamReader(fis,"gbk"); );
* 当hello.txt编码格式改为UTF-8时,代码改为InputStreamReader fr=new InputStreamReader(fis,"UTF-8"); 时才可以正常读取数据。
* */

public class BufferedReaderTest {
public static void main(String[] args) {
InputStreamReader fr = null;
BufferedReader br = null;
try {
FileInputStream fis = new FileInputStream("c:\\myDoc\\hello.txt");
// 指定编码格式
fr = new InputStreamReader(fis, "utf-8");
br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}

} catch (IOException e) {
try {
br.close();
fr.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(e.getMessage());
}
}

}

PrintWriter

java.io.PrintWriter是java中很常见的一个类,该类可用来创建一个文件并向文本文件写入数据。可以理解为java中的文件输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
 public static void main(String[] args) {
PrintWriter pw = null;
try {
pw = new PrintWriter("f://aaa.txt");

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.print("Hello World");
pw.close();
}

序列化(对象流)

序列化是将对象的状态写入到特定的流中的过程。
反序列化则是从特定的流中获取数据重新构建对象的过程。

序列化的步骤:
实现Serializable接口、创建对象输出流、调用writeObject0方法将对象写入文件、关闭对象输出流。

反序列化的步骤:
实现Serializable接口、创建对象输入流、调用readObject0方法读取对象、关闭对象输入流。

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class Student implements java.io.Serializable  {	
private String name;
private int age;
private String gender;
private transient String password;
public Student(String name, int age,String gender){
this.name=name;
this.age=age;
this.gender=gender;
}

public Student(String name, int age,String gender,String password){
this.name=name;
this.age=age;
this.gender=gender;
this.password=password;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}

public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}



import java.io.*;

public class SerializableObj {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream oos = null;
ObjectInputStream ois=null;
try {
// 创建ObjectOutputStream输出流
oos = new ObjectOutputStream(new FileOutputStream(
"c:\\myDoc\\stu.txt"));
Student stu = new Student("安娜", 30, "女","aaaa");
System.out.println("姓名为:"+stu.getName());
System.out.println("年龄为:"+stu.getAge());
System.out.println("性别为:"+stu.getGender());
System.out.println("密码为:"+stu.getPassword());
// 对象序列化,写入输出流
oos.writeObject(stu);

//创建ObjectInputStream输入流
ois=new ObjectInputStream(new FileInputStream("c:\\myDoc\\stu.txt"));
//反序列化,强转类型
Student stu1=(Student)ois.readObject();
//输出生成后对象信息
System.out.println("姓名为:"+stu1.getName());
System.out.println("年龄为:"+stu1.getAge());
System.out.println("性别为:"+stu1.getGender());
System.out.println("密码为:"+stu1.getPassword());
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (oos != null) {
oos.close();
}
if (ois != null) {
ois.close();
}
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

文章目录
  1. file
  2. IO流
    1. 按照流的方向进行分类
    2. 按照读取数据方式不同进行分类
    3. IO流四大家族首领
  3. 字节流
    1. java.io.FileInputStream
    2. java.io.FileOutputStream
    3. 文件复制
  4. 字符流
    1. BufferedReader
    2. PrintWriter
  5. 序列化(对象流)
|