IO流(常用流都有)

目录

一、流的分类:

二、流的体系结构

​三、FileReader和FileWriter

四、FileInputStream和FileOutputStream

五、BufferedInputStream和BufferedOutputStream(BufferedReader和Bufferedwriter)

六、InputStreamReader和OutputStreamWriter

八、PrintStream 和PrintWriter

九、DataInputStream 和 DataOutputStream

十、对象流ObjectInputStream和OjbectOutputStream

十一、RandomAccessFiLe的使用


 

一、流的分类:

1.操作数据单位:字节流、字符流
2.数据的流向:输入流、输出流
3.流的角色:节点流、处理流

二、流的体系结构


三、FileReader和FileWriter

 从内存中写出数据到硬盘的文件里

        说明:
    1.输出操作,对应的File可以不存在的。并不会报异常
    2.File对应的硬盘中的文件如果不存在:在输出的过程中,会自动创建此文件。
        FiLe对应的硬盘中的文件如果存在:
            如果流使用的构造器是:Filewriter(file,false) / Filewriter(file):对原有文件进行覆盖
            如果流使用的构造器是:Filewriter(file,true):在原有文件的内容基础上执行添加操作
     */
    @Test
    public void test3() {
        FileWriter fw = null;
        try {
//1.提供FiLe类的对象,指明写出到的文件
            File file = new File("dream");
//2.提供FiLewriter的对象,用于数据的写出
            fw = new FileWriter(file, true);
//3.写出的操作
            fw.write("I have a dream");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
//4.流资源的关闭
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }


    }

//3.数据的读入和写出操作
            char[] chars = new char[5];
            int len;
            while ((len = fr.read(chars)) != -1) {
                    fw.write(chars,0,len);//意思就是写出去len个
            }

 

测试FileInputStream和FileOutputStream的使用结论:
 *
 * 1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
 * 2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理
 *
 * @author haiyu
 * @create 2022/2/7-11:28
 */
public class FileInputOutputStreamTest {
//    实现对图片的复制
    @Test
    public void test1(){
        FileInputStream fis = null;
        FileOutputStream fos =null;
        try {
            File file = new File("励志.png");
            File file1 = new File("励志1.png");

            fis = new FileInputStream(file);
            fos = new FileOutputStream(file1);

            byte[] b = new byte[5];
            int len;

            while ((len = fis.read(b)) != -1){
                fos.write(b,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//我们发现都是固定格式的,所以自己定义一个copy()
    public void copy(String srcFile,String destFile){//String类型的形参 这里是路径
        FileInputStream fis = null;
        FileOutputStream fos =null;
        try {
            File file = new File(srcFile);
            File file1 = new File(destFile);

            fis = new FileInputStream(file);
            fos = new FileOutputStream(file1);

            byte[] b = new byte[1024];
            int len;

            while ((len = fis.read(b)) != -1){
                fos.write(b,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void test2(){
        String  srcFile = "C:\\Users\\17391\\Desktop\\视频1.mp4";
        String destFile = "C:\\Users\\17391\\Desktop\\视频2.mp4";

        long start = System.currentTimeMillis();

        copy(srcFile,destFile);
        System.out.println("复制完成");

        long end = System.currentTimeMillis();

        System.out.println("花费时间:" + (end - start));//1327

    }
}

四、FileInputStream和FileOutputStream

测试FileInputStream和FileOutputStream的使用结论:
 *
 * 1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
 * 2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理
 *
 * @author haiyu
 * @create 2022/2/7-11:28
 */
public class FileInputOutputStreamTest {
//    实现对图片的复制
    @Test
    public void test1(){
        FileInputStream fis = null;
        FileOutputStream fos =null;
        try {
            File file = new File("励志.png");
            File file1 = new File("励志1.png");

            fis = new FileInputStream(file);
            fos = new FileOutputStream(file1);

            byte[] b = new byte[5];
            int len;

            while ((len = fis.read(b)) != -1){
                fos.write(b,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

//我们发现都是固定格式的,所以自己定义一个copy()
    public void copy(String srcFile,String destFile){//String类型的形参 这里是路径
        FileInputStream fis = null;
        FileOutputStream fos =null;
        try {
            File file = new File(srcFile);
            File file1 = new File(destFile);

            fis = new FileInputStream(file);
            fos = new FileOutputStream(file1);

            byte[] b = new byte[1024];
            int len;

            while ((len = fis.read(b)) != -1){
                fos.write(b,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void test2(){
        String  srcFile = "C:\\Users\\17391\\Desktop\\视频1.mp4";
        String destFile = "C:\\Users\\17391\\Desktop\\视频2.mp4";

        long start = System.currentTimeMillis();

        copy(srcFile,destFile);
        System.out.println("复制完成");

        long end = System.currentTimeMillis();

        System.out.println("花费时间:" + (end - start));//1327

    }
}

五、BufferedInputStream和BufferedOutputStream(BufferedReader和Bufferedwriter)

处理流之一:缓冲流的使用
* 1.缓冲流:
* BufferedInputStream
* BufferedOutputStream
* BufferedReader
* Bufferedwriter
* <p>
* 2.作用:提供流的读取、写入的速度
public class BufferTest {
    @Test
    public void test1() {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            File srcFile = new File("励志.png");
            File destFile = new File("励志2.png");

            fileInputStream = new FileInputStream(srcFile);
            fileOutputStream = new FileOutputStream(destFile);

            bufferedInputStream = new BufferedInputStream(fileInputStream);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

            byte[] bytes = new byte[10];
            int len;
            while ((len = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.

            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
读写操作
//            方式一:
            char[] c = new char[5];
            int len;
            while ((len = br.read(c)) != -1){
                bw.write(c,0,len);
           }
//            方式二:
            String data;
            while ((data = br.readLine()) != null){
                //方法一:
               // bw.write(data+"\n");//不带换行符,自己加一个就好了
                //方法二:
                bw.write(data);
                bw.newLine();

六、InputStreamReader和OutputStreamWriter

1.转换流:属于字符流
* InputStreamReader:将一个字节的输入流转换为字符的输入流
* outputstreamwriter:将一个字符的输出流转换为字节的输出流
*
* 2.作用:提供字节流与字符流之间的转换
*
* 3.解码:字节、字节数组--->字符数组、字符串
*    编码:字符数组、字符串--->字节、字节数组
*
* 4.字符集
 /*
    InputStreamReader:实现字节输入流到字符输入流的转化
     */
    @Test
    public void test1(){
        InputStreamReader isr = null;
        try {
            FileInputStream fis = new FileInputStream("dream");
//        InputStreamReader isr = new InputStreamReader(fis);
//        参数二表明类字符集,具体使用哪个字符集需要看文件当时按照哪个储存的。
            isr = new InputStreamReader(fis,"UTF-8");

            char[] c = new char[5];
            int len;
            while ((len = isr.read(c)) != -1){
                String s = new String(c,0,len);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (isr != null){
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    /*
    综合使用InputStreamReader 和  OutputStreamWriter

    代码分析:
    hello.txt在源文件中是以utf-8的编码表来储存的,我们这里将他读取在内存中的一个字符串中展示在控制台,
    我们还想把读到内存中的字符以gbk的那个编码表存到hello.gbk.txt文件中,所以我们现在用idea的utf-8的编
    码表不能正常阅读出hello.gbk.txt文件

     */
    @Test
    public void test2(){


        InputStreamReader isr = null;
        OutputStreamWriter osr = null;
        try {
            FileInputStream fis = new FileInputStream("hello.txt");
            FileOutputStream fos = new FileOutputStream("hello.gbk.txt");

            isr = new InputStreamReader(fis,"utf-8");
            osr = new OutputStreamWriter(fos,"gbk");

            char[] c = new char[20];
            int len;
            while ((len = isr.read(c)) != -1){
                String s = new String(c, 0, len);
                System.out.print(s);

                osr.write(c,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (isr != null){
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
            if (osr != null){
                try {
                    osr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    }

七、System.in和System.out

标准的输入、输出流
    1.1
    System.in:标准的输入流,默认从键盘输入
    System.out:标准的输出流,默认从挽制台输出
    1.2
    System类的setIn(InputStream is) / setOut(printStream ps)方式重新指定输入和输出的流。


    1.3练习:
从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
直至当输入“e”或者“exit时,退出程序。
方法一:使用Scanner实现
方法二:使用system. in实现:System.in--->InputStreamReader--->BufferReader的readerLine()

     */
    public static void main(String[] args) {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                System.out.println("输入字符串");
                String s = bufferedReader.readLine();

                if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) {//这里这样写使得程序代码更健壮
                    System.out.println("结束");
                    break;
                } else {
                    String s1 = s.toUpperCase();
                    System.out.println(s1);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

八、PrintStream 和PrintWriter

提供了-系列重载的print()和println()

九、DataInputStream 和 DataOutputStream

作用:用于读取或写出基本数据类型的变量或字符串
     */

//    练习:将内存中的字符串、基本数据类型写出到文件中
    @Test
    public void test3(){
        DataOutputStream dos = null;
        try {
            dos = new DataOutputStream(new FileOutputStream(new File("hello.txt")));

            dos.writeInt(23);
            dos.flush();//刷新操作,执行时会把数据写入到文件中  自己不是必须要写,writer都自带的
            dos.writeBoolean(true);
            dos.flush();
            dos.writeUTF("我要15w");
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dos !=null){
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//    练习:写到文件中的基本数据类型、字符串读取到内存中,保存在一个变量中。
//    注意点: 读取数据类型的顺序要和保存时一致
    @Test
    public void test4(){
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new FileInputStream("hello.txt"));

            int age = dis.readInt();
            boolean isMale = dis.readBoolean();
            String aim = dis.readUTF();

            System.out.println("age = " + age + ",isMale = "+ isMale + ",aim = " + aim);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dis != null){

                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

十、对象流ObjectInputStream和OjbectOutputStream

作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,
 * 也能把对象从数据源中还原回来
 *
 * 要想一个对象满足序列化,有一定的要求:见Person.java
 */
public class ObjectInputStream {
    /*
    序列化过程:将内存中的java对象保存到磁盘中,或者通过网络的方式传输出去
    使用ObjectOutputStream实现
     */
    @Test
    public void test1() {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));

            oos.writeObject(new String("我爱人民币"));
            oos.flush();

            oos.writeObject(new Person(12,"haiyu"));
            oos.flush();


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {

                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /*
    反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象。

    注意:ObjectInputStream有java.io下的,居然还有java6下的,应该选前者,后者没有read方法。
     */
    @Test
    public void test2(){
        java.io.ObjectInputStream ois = null;
        try {
            ois = new java.io.ObjectInputStream(new FileInputStream("object.dat"));

            Object object = ois.readObject();
            String s = (String)object;

            Person p  = (Person)ois.readObject();//对象的反序列化

            System.out.println(s);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois != null){

                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }



    }
Person需要满足如下的要求,方可序列化
*1.需要实现接口:Serializable
* 2.需要当前类提供全局常量:serialVersionUID
* 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性
* 也必须是可序列化的。(默认基本数据类型是可以序列化的)
* 如果自定义类中一个属性也是自定义类,那么这个属性的类也必须实现Serializable接口,并提供全局常量。
*
* 补充: ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。
public class Person implements Serializable {

    public static final long serialVersionUID = 416516L;

    private int age;
    private String name;

    public Person() {
    }

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

十一、RandomAccessFiLe的使用

1.RandomAccessFile直接继承于java.Lang.0bject类,实现了DataInput和DataOutput接口
* 2.RandomAccessFiLe既可以作为一个输入流,又可以作为一个输出流
* 3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建
* 如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头履盖)
* 4.可以通过相关的操作,实现RandomAccessFiLe*插入”数据的效果
方法:seek(int i):把角标调的i位置
@Test
    public void test1(){
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            raf1 = new RandomAccessFile(new File("励志.png"),"r");
            raf2 = new RandomAccessFile(new File("励志随机存取文件流.png"),"rw");

            byte[] b  = new byte[1024];
            int len;
            while ((len = raf1.read(b)) != -1){
                raf2.write(b,0,len);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf2 != null){
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }


    }

    @Test
    public void test2(){
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(new File("hello.txt"),"rw");

            raf.seek(3);//将指针调到角标为3的位置。 这里是英文字母的角标,(因为字母是一个字节,汉字是三个字节)

            raf.write("xyz".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf != null){

                try {
                    raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    /*
    使用RandomAccessFile实现插入的效果
     */

    @Test
    public void test3(){
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(new File("hello1.txt"),"rw");

            raf.seek(3);
            //保存指针后面的所有数据到sb中
            StringBuilder sb = new StringBuilder("hello1.txt".length());
            byte[] b = new byte[10];
            int len;
            while ((len = raf.read(b)) != -1){
                sb.append(new String(b,0,len));
            }

            raf.seek(3);
            raf.write("xyz".getBytes());
            //sb里面的数据再写上。
            raf.write(sb.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf != null){

                try {
                    raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java塑造中...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值