【io】流及File对象的处理(一)

IO的处理

1. 【io】流及File对象的处理(一)

2. 【io】流及File对象的处理(二)

 

本文主要介绍流的相关内容

1. 流的概念

是内存与存储设备之间传输数据的通道。

 

2. 流的分类

# 1. 按照方向分:
(1)输入流:将<存储设备>中的内容读入到<内存>中
(2)输出流:将<内存>中的内容写入到<存储设备># 2. 按处理单位分:
(1)字节流:以字节为单位,可以读写所有数据
(2)字符流:以字符为单位,只能读写文本数据
# 3. 按功能分:
(1)节点流:具有实际传输数据的读写功能。
(2)过滤流:在节点流的基础之上增强功能。

 

3. 字节流

3.1 字节流

# 字节流的父类(抽象类)
(1)InputStream:字节输入流(read)
(2)OutputStream:字节输出流(write)
# 文件字节流
    #(1)FileInputStream:
    #(2)FileOutputStream:

例子:

# 单个字节读取
public static void main(String[] args) throws Exception {//这里为了代码可读性,异常暂时抛出
    //1. 创建FileInputStream,并指定文件路径
    FileInputStream fis = new FileInputStream("d:\\aa.txt");
    //2. 读取文件 data对象用来保存我们读取的字节
    int data = 0;
    //如果都读取完了,会返回-1 ,不过这个read方法读取比较慢,是一个字节一个字节的读
    while ((data=fis.read())!=-1){
    System.out.println((char)data);//假设txt文件中存的是abcdefg ,那么每次会输出一个
    }
    //3. 关闭
    fis.close();
}

# 多个字节读取
public static void main(String[] args)  throws Exception{
    //1. 创建FileInputStream,并指定文件路径
    FileInputStream fis = new FileInputStream("d:\\aa.txt");
    //2. 创建一个数组用来存放读取到的字节,这里暂定长度为3
    byte[] buf = new byte[3];
    //3. 读取文件 count就是我们实际读取的字节数
    int count = 0;
    //如果都读取完了,会返回-1 ,这个read方法,是按照上面数组的长度,即三个三个的读
    while ((count=fis.read(buf))!=-1){
    System.out.println(new String(buf,0,count));//假设txt文件中存的是abcdefg ,那么每次会输出三个
    }
    //4. 关闭
    fis.close();
}

# 输出流写入
public static void main(String[] args) throws Exception{
    //1. 创建文件字节输出流对象 ,没有此文件会创建,有此文件调用下面的write方法的时候会覆盖txt里的内容。
    FileOutputStream fos = new FileOutputStream("d:\\bb.txt");
    //可以通过加参数 true 来实现非覆盖而是追加的效果
    //FileOutputStream fos = new FileOutputStream("d:\\bb.txt",true);
    //2. 写入文件.
    String str = "helloword";
    //str.getBytes()意思为获取这个字符串所对应的字符数组
    fos.write(str.getBytes());
    //3. 关闭
    fos.close();
}

# 使用文件字节流(输入流和输出流)实现文件的复制
# 注意:文件字节流不带缓冲效率会比较低
public static void main(String[] args) throws Exception{
    //1. 创建流
    //1.1 文件字节输入流 ,如果没有会报错java.io.FileNotFoundException: d:\001.jpg (系统找不到指定的文件。)
    FileInputStream fis = new FileInputStream("d:\\001.jpg");
    //1.2 文件字节输出流
    FileOutputStream fos = new FileOutputStream("d:\\002.jpg");
    //2. 一边读,一边写
    byte[] buf = new byte[1024];
    int count =0;
    while((count=fis.read(buf))!=-1){
    fos.write(buf,0,count);
    }
    //3. 关闭
    fis.close();
    fos.close();
}
View Code

3.2 字节缓冲流

# 缓冲流:BufferedInputStream/BufferedOutputStream
(1)提高IO效率,减少访问磁盘的次数
(2)数据存储在缓存区中,flush是将缓存区的内容写入文件中,也可以直接close.

例子:

//输入缓冲流
public static void main(String[] args) throws Exception{
    //1. 创建文件输入流
    FileInputStream fis = new FileInputStream("d:\\aa.txt");
    //2. 创建缓冲流,来增强文件输入流
    BufferedInputStream bis = new BufferedInputStream(fis);
    //3. 读取
    int data = 0;
    //注意:这里read并非一个个的读,而是一次读8k到缓冲区,即BufferedInputStream源码中的private static int DEFAULT_BUFFER_SIZE = 8192;
    while ((data=bis.read())!=-1){
        System.out.println((char)data);
    }

    //当然也可以自己定义缓冲区
    //byte[] buf = new byte[1024];
    //int count =0;
    //while ((count=bis.read(buf))!=-1){
        //System.out.println(new String(buf,0,count));
    //}

    //4. 关闭 只关闭缓冲流即可,它内部会把文件输入流也关闭了.
    bis.close();
}


//输出缓冲流
public static void main(String[] args) throws Exception{
    //1. 创建字节输出流
    FileOutputStream fos = new FileOutputStream("d:\\cc.txt");
    //2. 创建字节输出缓冲流
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    //3. 写入文件
    for(int i=0;i<10;i++){
    bos.write("helloworld".getBytes());//只要不超过8k都会写入到8k缓冲区,此时文件中实际上是没有内容的
    bos.flush();//只有刷新才会将数据刷新到硬盘
    }
    //4. 关闭(内部也会调用flush方法)
    bos.close();
}
View Code

3.3 对象流+(反)序列号 

Serializable接口
# 对象流:ObjectOutputStream/ObjectInputStream 使用流传输对象的过程称为序列化/反序列化
(1)增强了缓冲区功能
(2)增强了读写8中基本数据类型和字符串功能
(3)增强了读写对象的功能 readObject() 从流中读取一个对象  writeObject(Object obj) 向流中写入一个对象
# 要求:
(1)序列化类必须要实现Serializable接口
(2)序列化类中对象属性也要求实现Serializable接口
(3)序列化版本号ID(serialVersionUID),保证序列化的类和反序列化的类是同一个类
(4)使用transient(瞬间的)修饰属性,这个属性不能序列化
(5)静态属性也不能序列化
(6)序列化多个对象 即下面的例子中可以创建多个对象,之后将多个对象放入一个list中,当然获取的时候返回的也是一个List即可

例子:

//使用ObjectOutputStream实现对象的序列化 
public static void main(String[] args) throws Exception{
    //1. 创建文件输出流
    FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
    //2. 创建文件输入流
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    //3. 创建一个对象并赋值
    //注意:这里要求必须要对象实现序列化,否则会报错java.io.NotSerializableException: com.company.Student
    Student stu = new Student();
    stu.setAge(21);
    stu.setName("张三");
    //4. 写入操作(序列化)
    oos.writeObject(stu);
    //5. 关闭
    oos.close();
}

//这里要求对象必须实现序列化
public class Student implements Serializable {
    private String name;
    private int age;
    //private transient int age;//被transient修饰的不能序列化,即序列化后再反序列化是没值的
    private static final long serialVersionUID = -8778349856468359639L;
    //省略setter、getter、toString方法
}

//使用ObjectInputStream实现反序列化(读取重构成对象)
public static void main(String[] args) throws Exception{
    //1. 创建文件输入流
    FileInputStream fis = new FileInputStream("d:\\stu.bin");
    //2. 创建对象流
    ObjectInputStream ois = new ObjectInputStream(fis);
    //3. 读取文件(反序列化)
    Student stu = (Student)ois.readObject();
    //4. 关闭
    ois.close();
    System.out.println(stu.toString());//结果:  Student{name='张三', age=21}
}
View Code

 

4. 编码方式

# 常见字符编码
# 1. ISO-8859-1 收录除了ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
# 2. UTF-8  针对Unicode码表的可变长度字符编码
# 3. GB2312 简体中文
# 4. GBK  简体中文、扩充
# 5. BIG5  台湾,简体中文
# 当编码方式和解码方式不一致时,会出现乱码。

 

5. 字符流

5.1 字符流

# 涉及到汉字的一般用字符流 FileReader/FileWriter
# 字符流的父类(抽象类):
(1)Reader:字符输入流  read()
(2)Writer:字符输出流  write()

例子:

//FileReader读取文件
public static void main(String[] args) throws Exception{
    //1. 创建FileReader 文件字符输入流
    FileReader fr = new FileReader("d:\\hello.txt");
    //2. 读取 (单个字符读取)
    int data = 0;
    while ((data=fr.read())!=-1){
        System.out.println((char)data);
    }
    //3. 关闭
    fr.close();
}

//FileWriter写入文件
public static void main(String[] args) throws Exception{
    //1. 创建FileWriter对象
    FileWriter fw = new FileWriter("d:\\write.txt");
    //2. 写入
    for(int i=0;i<10;i++){
        fw.write("你好");
        fw.flush();
    }
    //3. 关闭
    fw.close();
}

//使用FileWriter和FileReader复制文件
//注意:只能复制文本文件,不能复制图片和二进制文件(声音/视频等) 字节流可以复制任何文件
public static void main(String[] args) throws Exception{
    //1. 创建FileWriter和FileReader
    FileReader fr = new FileReader("d:\\write.txt");
    FileWriter fw = new FileWriter("d:\\write2.txt");
    //2. 读写
    int data=0;
    while ((data=fr.read())!= -1){
        fw.write(data);
        fw.flush();
    }
    //3. 关闭
    fr.close();
    fw.close();
}
View Code

5.2 字符缓冲流

# 缓冲流:BufferedReader/BufferedWriter
(1)高效读写(缓冲区)
(2)支持输入换行符
(3)可一次读/写一行

例子:

//使用字符缓冲流读取文件 (单个字符读+一行一行读)
public static void main(String[] args) throws Exception{
    //1. 创建缓冲流
    FileReader fr = new FileReader("d:\\write.txt");
    BufferedReader br = new BufferedReader(fr);
    //2. 读取
    //2.1 第一种
    //char[] buf = new char[1024];
    //int count = 0;
    //while ((count=br.read())!=-1){
    //System.out.println(new String(buf,0,count));
    //}
    //2.2 第二种 一行一行读
    String line = null;
    while ((line=br.readLine())!=null){
        System.out.println(line);
    }
    //3. 关闭
    br.close();
}

//使用字符缓冲流写入文件
public static void main(String[] args) throws Exception{
    //1. 创建缓冲流
    FileWriter fw = new FileWriter("d:\\buffer.txt");
    BufferedWriter bw = new BufferedWriter(fw);
    //2. 写入
    for(int i=0;i<10;i++){
        bw.write("你好");
        bw.newLine();//写入一个换行符 windows:\r\n   linux:\n
        bw.flush();
    }
    //3. 关闭
    bw.close();
}
View Code

 

6. 打印流

# PrintWriter:
(1)封装了print() / println() 方法,支持写入后换行
(2)支持数据原样打印

例子:

//PrintWriter的使用
public static void main(String[] args) throws Exception{
    //1. 创建打印流
    PrintWriter pw = new PrintWriter("");
    //2. 打印
    pw.println(97);//换行 打印到文件之后不会变成a,仍然是97
    pw.print(true);//不换行 打印到文件里是true字符串
    pw.println('a');//打印到文件里是a
    //3. 关闭
    pw.close();
}
View Code

 

7. 转换流

# 又称为桥转换流:InputStreamReader/OutputStreamWriter
(1)可将字节流转换为字符流
(2)可设置字符的编码方式

例子:

//使用InputStreamReader读取文件,指定使用的编码
public static void main(String[] args) throws Exception{
    //1. 创建InputStreamReader对象
    FileInputStream fis = new FileInputStream("d:\\write.txt");
    InputStreamReader isr = new InputStreamReader(fis,"utf-8");//gbk
    //2. 读取文件
    int data=0;
    while ((data=isr.read())!=-1){
        System.out.println((char)data);
    }
    //3. 关闭
    isr.close();
}

//使用OutputStreamWriter写入文件,指定使用的编码
public static void main(String[] args) throws Exception{
    //1. 创建OutputStreamWriter对象
    FileOutputStream fos = new FileOutputStream("d:\\info.txt");
    OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
    //2. 写入文件
    for(int i=0;i<10;i++){
        osw.write("你好");
        osw.flush();
    }
    //3. 关闭
    osw.close();
}
View Code

 

 

 

持续更新!!!

posted @ 2021-04-25 15:38  夏夜凉凉  阅读(204)  评论(0编辑  收藏  举报