Day14-Java I/O

Java I/O流

img

流的概念

内存与存储设备之间的通道

image-20210219162051665

流的分类

按方向

  • 输入流:将存储设备中的内容读取到内存
  • 输出流:将内存中的内容写入存储设备

image-20210219162323393

按单位

  • 字节流:以字节为单位,可以读取数据(任意数据)
  • 字符流:以字符为单位,只能读写文本数据

按功能

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础上增强了功能

字节流

两个抽象类,是所有输入输出类的超类,定义了一些方法

  • InputStream
  • OutputStream

文件字节流

  • FileInputStream

    • public int read(byte[] b),从流中读取多个字节,将读取内容存入b数组,返回实际读到的字节数,如果达到文件底部,返回-1
    package IIIOOO;
    
    import java.io.File;
    import java.io.FileInputStream;
    
    public class FiileInputStramT {
        public static void main(String[] args) throws Exception {
            //1.创建文本对象
            FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\haha.txt");
    
            //2.读取文件
                //2.1单个字节读取
             int data = 0;
             while ((data=fis.read())!=-1){
                 System.out.println((char)data);        //效率慢,一次只能读取一个
             }
            System.out.println("-------------------------");
                //2.2多个字节读取
            byte[] arr = new byte[3];                   //2.1已经将文件读取完了,得注释后才有效果
            int count = 0;
            while ((count=fis.read(arr))!=-1){
                System.out.print(new String(arr,0,count));    //offset开始位置,count--->要解码的字节数
            }
            
            
            
            fis.close();
        }
    }
    
    
  • FileOutputStream

    • public int write(byte[] b),一次性写入多个字节,将b数组中的所有字节写入输出流
    package IIIOOO;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class FileOutStreamT {
        public static void main(String[] args) throws IOException {
            //1.创建对象
            FileOutputStream fis = new FileOutputStream("D:\\code\\JavaSE\\files\\haha.txt",true);  //添加true,写入字节时,追加而不是覆盖
    
            //2.写入文件
                //2.1单个字节写入
            fis.write(98);
            fis.write('c');
            fis.write('w');
                //2.2多个字节书写
            String s = "Hello World!";
            fis.write(s.getBytes());
    
            //3.关闭
            fis.close();
        }
    }
    
    
复制文件
package IIIOOO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\2.jpg");
        FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\1.jpg");

        //2.读取与写入
        byte[] arr = new byte[1024];
        int count = 0 ;
        while ((count=fis.read(arr))!=0){
            fos.write(arr,0,count);
        }

        //3.关闭
        fis.close();
        fos.close();
    }
}

字节缓冲流

  • BufferedInputStream/BufferedOutputStream,增强节点流或者底层流

1.减少访问磁盘的次数,提高i/o的效率

2.数据存储在缓冲区中,flush将缓冲区中的内容写入文件中,也可以直接close

package IIIOOO;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class BufferedInputStreamT {
    public static void main(String[] args) throws Exception {
        //1.创建对象
        FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\haha.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        //2.读取数据
        byte[] arr = new byte[1024];        //自己写一个缓冲区为1k
        int count=0;
        while ((count=bis.read(arr))!=-1){
            System.out.println(new String(arr,0,count));
        }

        while ((count=bis.read())!=-1){     //自带缓冲区为8k
            System.out.println(new String(arr,0,count));
        }


        //3.关闭
        fis.close();
        bis.close();
    }
}

package IIIOOO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class ObjectOutputStreamT {
    public static void main(String[] args)throws Exception {
        //1.创建对象流
        FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Student s1 = new Student("程晨橙",18);     //利用transient修饰,可以让部分属性不被序列化
        Student s2 = new Student("黄黄华南",24);

        //2.写入对象
//        oos.writeObject(s1);
//        oos.writeObject(s2);
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        oos.writeObject(list);

        //3.关闭
        fos.close();
        oos.close();

    }
}

对象流

ObjectOutputStream/ObjectInputStream

特点:

1.增强了缓冲区功能

2.增强了读写八种基本数据类型和字符串功能

3.增强了读写对象的功能

4.写入的对象类必须实现一个接口Serializable(仅起标识可以序列化的作用)

使用流传输对象的过程称为序列化、反序列化

序列化

将对象写入存储设备中

package IIIOOO;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamT {
    public static void main(String[] args)throws Exception {
        //1.创建对象流
        FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Student s1 = new Student("程晨橙",18);
        Student s2 = new Student("黄黄华南",24);

        //2.写入对象
        oos.writeObject(s1);
        oos.writeObject(s2);

        //3.关闭
        fos.close();
        oos.close();
    }
}

反序列化

从存储设备中读取对象

package IIIOOO;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.List;

public class ObjectInputStramT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);

        //2.读取对象
//        Student s =(Student)ois.readObject();
        List<Student> list = (List<Student>)ois.readObject();
        System.out.println(list.toString());

        //3.关闭
        ois.close();
    }
}

注意事项

1.当创建对象的类中包含类时,该类也需要实现Serializable接口

2.序列化与反序列化类的版本号id需要相同,否则会报错

3.使用transient(瞬间的)修饰不想序列化的属性

4.静态属性不能序列化

5.可以使用集合放置对象,再将集合写入存储设备

字符流

UTF-8中汉字为三个字节一个字,如果使用字节流,则会出现乱码问题

  • Reader:字符输入流
package IIIOOO;

import java.io.FileReader;

public class FileReaderT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileReader frd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");

        //2.读取数据
//        int data = 0;
//        while ((data=frd.read())!=-1){
//            System.out.print((char)data);
//        }
        char[] arr = new char[1024];
        int count=0;
        while ((count=frd.read(arr))!=-1){          //第一次直接读取1k的数据存放再arr中,后续在缓冲区中读取,提高i/o效率
            System.out.println(new String(arr,0,count));
        }

        //3.关闭
        frd.close();
    }
}

  • Writer:字符输出流
package IIIOOO;

import java.io.FileWriter;

public class FileWriterT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileWriter fwr= new FileWriter("D:\\code\\JavaSE\\files\\中文.txt",true);

        //2.写入数据
        String s = "\r\n早睡早起";
        fwr.write(s);

        //3.关闭
        fwr.close();
    }
}

复制文件

只能复制文本文件

package IIIOOO;

import java.io.FileReader;
import java.io.FileWriter;

public class CopyTxt {
    public static void main(String[] args) throws Exception {       //只能复制文本文件
        //1.创建对象流
        FileReader frd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");
        FileWriter fwr = new FileWriter("D:\\code\\JavaSE\\files\\中文副本.txt");

        //2.复制
        char[] arr = new char[1024];
        int count = 0;
        while ((count=frd.read(arr))!=-1){
            fwr.write(new String(arr,0,count));
            fwr.flush();
        }

        //3.关闭
        frd.close();
        fwr.close();
    }
}

字符缓冲流

  • 缓冲流:BufferedReader/BufferedWriter
    • 高效读写
    • 支持输入换行符
    • 可以一次写一行、读一行
package IIIOOO;

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferedReaderT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileReader fwd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");
        BufferedReader bwd = new BufferedReader(fwd);

        //2.读取数据
//        char[] arr = new char[1024];
//        int count = 0 ;
//        while ((count=bwd.read(arr))!=-1){
//            System.out.println(new String(arr,0,count));
//        }
        String line = null;
        while ((line=bwd.readLine())!=null){
            System.out.println(line);
        }
    }
}

package IIIOOO;

import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferedWriterT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileWriter fwr = new FileWriter("D:\\code\\JavaSE\\files\\中文.txt");
        BufferedWriter bwr = new BufferedWriter(fwr);

        //2.写入数据
        for (int i = 0; i <10 ; i++) {
            bwr.write("勤勤恳恳");
            bwr.newLine();
            bwr.flush();
        }

    }
}

打印流

  • 封装了print()/printn()方法,支持写入后换行

  • 支持数据原样打印

打印会覆盖?

package IIIOOO;

import java.io.PrintWriter;

public class PrintWriterT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        PrintWriter pwr = new PrintWriter("D:\\code\\JavaSE\\files\\中文.txt");

        //2.写入数据
        pwr.println("尝试打印");
        pwr.println(3.1415926);
        pwr.println('x');
        pwr.print("?");
        pwr.write(98);

        //3.关闭
        pwr.close();
    }
}

转换流

  • 桥转换流:InputStreamReader/OutputStreamWriter
    • 可以将字节流转换为字符流
    • 可设置字符的编码方式
package IIIOOO;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class OutputStreamWriterT {
    public static void main(String[] args) throws Exception {
        //1.创建对象流
        FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\转换流.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");

        //2.写入数据
        for (int i = 0; i <10 ; i++) {
            osw.append("好好学习,天天向上\r\n");
        }

        //3.关闭
        osw.close();
    }
}




package IIIOOO;

import java.io.FileInputStream;
import java.io.InputStreamReader;

public class InputSteamReaderT {
    public static void main(String[] args)  throws Exception {
        //1.创建对象流
        FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\转换流.txt");
        InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //字符编码

        //2.读取数据
//        byte[] arr = new byte[1];       //一个中文三个字节,所以一个字节时将会乱码
//        int count =0;
//        while ((count=fis.read(arr))!=-1){
//            System.out.println(new String(arr,0,count));
//        }
        int data = 0;
        while ((data=isr.read())!=-1){
            System.out.print((char)data);
        }

        //3.关闭
        isr.close();
    }
}

posted @ 2021-02-20 22:07  2月2日  阅读(46)  评论(0)    收藏  举报