java 流详解

1.流的分类

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

四个最基本的抽象基类InputStream,OutputStream,Writer,Reader

流分类图
在这里插入图片描述

2.FileWriter和FileReader(字符流)基本使用

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @Author wfj
 * @Date 2021/6/28
 * @Description
 * @Version 1.0
 */

public class FileWriterReaderTest {
    /**
     * 一、流的分类
     * 1.操作数据单位:字节流,字符流
     * 2.数据的流向:输入流,输出流
     * 3.流的角色:节点流,处理流
     *
     * 二、流的体系结构
     * 抽象基类             节点流                                         缓冲流
     * InputStream          FileInputStream(read(byte[] cbuff))             BufferedInputStream(read(byte[] cbuff))
     * OutPutStream         FileOutputStream(write(byte[] cbuff,0,len))     BufferedOutputStream(write(byte[] cbuff,0,len),flush())
     * Reader               FileReader(read(char[] cbuff))                  BufferedReader(read(char[] cbuff) / readLine())
     * Writer               FileWriter(write(char[] cbuff,0,len))           BufferedWriter (write(char[] cbuff,0,len))
     */

    @Test
    public void test1() {
        FileReader fileReader = null;
        try {
            File file = new File("D:\\test\\test1\\bb.txt");
            //提供流
            fileReader = new FileReader(file);
            //数据的读入
            //read(): 返回读入的的一个字符,如果达到文件末尾,就返回-1
            //方式一:
//        int data = fileReader.read();
//        while (data != -1) {
//            System.out.print((char)data);//hellovue
//            //循环继续读取下一个字符
//            data = fileReader.read();
//        }

            //方式二:语法优化
            int data;
            while ((data = fileReader.read()) != -1) {
                System.out.print((char)data);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //流的关闭操作
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //对read()操作升级,使用read的重载方法
    @Test
    public void test2() {
        //1.实例化File类
        FileReader fileReader = null;
        try {
            File file = new File("D:\\test\\test1\\bb.txt");
            //2.提供流
            fileReader = new FileReader(file);
            //3.读入的操作
            //read(char[] cbuff):返回每次读入cbuff数组中的字符的个数(可以理解为每次从文件中读取指定多少个的字符,赋值到数组再返回),如果达到文件末尾,返回-1
            /**
             * 注意:这里有个坑,相对于以下方法一:错误的写法而言为什么不行呢?
             * 假设要读取文件的内容为hellojavavue
             * 第一次读到五个字符hello
             * 第二次读到五个字符javav
             * 第三次读到两个字符ue
             * 每次读到的字符都存储到cbuff数组,并不是去新建一个的,它们共用一个数组,所以按照以下错误的写法,
             * 当读到第三次时,数组中的元素会变为uevav(因为上一次数组的内容是javav,其只会替换内容,如果不全部替换,余下的内容还是上一次的内容)。显然出错
             */
            char[] cbuff = new char[5];
            int len;
            while ((len = fileReader.read(cbuff)) != -1) {
                //方法一:错误的写法
//                for (int i = 0; i < cbuff.length; i++) {
//                    System.out.println(cbuff[i]);
//                }
                //正确的写法:其实就是每次读到多少个字符,就遍历多少次
                for (int i = 0; i < len; i++) {
                    System.out.println(cbuff[i]);
                }
                //或者这样
//                String str = new String(cbuff,0,len);
//                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                //4.资源的关闭
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从内存中写数据到硬盘的文件里
     * 注意:file可以是不存在的
     * 如果file不存在,则会新建这个file
     * 如果file存在了:
     *      如果流使用的构造器是:FileWriter(file,false) / FileWriter(file) : 对原有的文件覆盖
     *      如果使用的构造器是:FileWriter(file,true) : 在原来文件的内容上进行追加新的内容
     */
    @Test
    public void tes3() {
        //1.提供File类
        FileWriter fileWriter = null;
        try {
            File file = new File("D:\\test\\test1\\bb.txt");
            //2.提供流
            fileWriter = new FileWriter(file);
            //3.写数据
            fileWriter.write("the ping i ping\n");
            fileWriter.write("fruit no bb");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileWriter != null) {
                //4.关闭流
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读入一个文件的内容,写出到另一个文件(复制)
    //注意:FileReader和FileWriter只能适用于字符数据的读写,对于图片等字节数据是不支持的
    @Test
    public void test4() {
        FileReader fileReader = null;
        FileWriter fileWriter = null;
        try {
            //创建File
            File file1 = new File("D:\\test\\test1\\bb.txt");
            File file2 = new File("D:\\test\\test1\\bbb.txt");
            //创建流
            fileReader = new FileReader(file1);
            fileWriter = new FileWriter(file2);
            char[] cbuff = new char[5];
            int len;
            //读写数据
            while((len = fileReader.read(cbuff)) != -1) {
                //读入多少个字符,就写出多少个字符
                fileWriter.write(cbuff,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.FileInputStream和FileOutputStream(字节流)基本使用

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

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

/**
 * @Author wfj
 * @Date 2021/6/28
 * @Description 字节流
 * @Version 1.0
 */

public class FileInputOutputStreamTest {

    /**
     * 注意:
     *  对于文本文件(.txt,.java,.c),使用字符流处理
     *  对于非文本文件(图片,.doc等),使用字节流处理
     */
    @Test
    public void test1() {
        FileInputStream fis = null;
        try {
            //创建file
            File file = new File("D:\\test\\test1\\bb.txt");
            //创建流
            fis = new FileInputStream(file);
            //读数据,这里注意:如果有中文会出现乱码,一个中文对应三个字节,每次读五个字节,会到中文对应的字节存在两个不同的数组里
            byte[] bytes = new byte[5];
            int len;
            while((len = fis.read(bytes)) != -1) {
                String str = new String(bytes,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                //关闭流
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //实现图片的复制
    @Test
    public void test2() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建file
            File file1 = new File("D:\\test\\test1\\11.jpg");
            File file2 = new File("D:\\test\\test1\\132.jpg");
            //创建流
            fis = new FileInputStream(file1);
            fos = new FileOutputStream(file2);
            //读写数据
            byte[] bytes = new byte[1024];
            int len;//记录每次读取到的个数
            //fis.read(bytes),返回读取到的字节个数,并且将读取到的内容,赋值到bytes数组里
            while((len = fis.read(bytes)) != -1) {
                //每次读到多少个字节,就写出多少个字节
                fos.write(bytes,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();
                }
            }
        }
    }
}

4.缓冲流的基本使用

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author wfj
 * @Date 2021/6/28
 * @Description 缓冲流: 提高流的读取和写入的速度
 * @Version 1.0
 */

public class BufferedTest {

    //比较普通的输入输出流和缓冲流的读写效率
    @Test
    public void test1() {
       String src = "D:\\test\\test1\\11.jpg";
       String dest = "D:\\test\\test1\\c11.jpg";
       long start = System.currentTimeMillis();
       copyImgByCommon(src,dest);
       long end = System.currentTimeMillis();
       //由于图片较小,所以比较快,但是缓冲流效率还是比普通的输入输出流高的
       System.out.println("普通输入输出流复制图片花费的毫秒数:" + (end-start));//2ms
       long start1 = System.currentTimeMillis();
       copayImgByBuffer(src,dest);
       long end1 = System.currentTimeMillis();
       System.out.println("缓冲流复制图片花费的毫秒数:" + (end1-start1));//1ms

    }

    //普通输入输出流复制图片
    public void copyImgByCommon(String src,String dest) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File file1 = new File(src);
            File file2 = new File(dest);
            fis = new FileInputStream(file1);
            fos = new FileOutputStream(file2);
            byte[] bytes = new byte[1024];
            int len;
            while((len = fis.read(bytes)) != -1) {
                fos.write(bytes,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();
                }
            }
        }
    }

    //缓冲流复制图片
    private void copayImgByBuffer(String src,String dest) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            File file1 = new File(src);
            File file2 = new File(dest);
            FileInputStream fis = new FileInputStream(file1);
            FileOutputStream fos = new FileOutputStream(file2);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            //读写数据
            byte[] bytes = new byte[1024];
            int len;
            while((len = bis.read(bytes)) != -1) {
                bos.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流,只需要关闭外层的流就行了,内部其实也关闭了内层的流
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //使用字符缓冲流复制txt文件
    @Test
    public void test2() {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(new File("D:\\test\\test1\\ha.txt")));
            bufferedWriter = new BufferedWriter(new FileWriter(new File("D:\\test\\test1\\ah.txt")));
            //读写数据
            //方式一
//            char[] cbuff = new char[1024];
//            int len;
//            while((len = bufferedReader.read(cbuff)) != -1) {
//                bufferedWriter.write(cbuff,0,len);
//            }
            //方式二:一行一行得读,注意:其不会换行的,我们要自己加上转义字符来换行
            String data;
            while((data = bufferedReader.readLine()) != null) {
                //方法一
//                bufferedWriter.write(data + "\n");
                //方法二
                bufferedWriter.write(data);
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader!= null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

5.InputStreamReader和InputStreamWriter(转换流)基本使用

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.*;

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description 转换流
 * @Version 1.0
 */

public class InputStreamReaderTest {
    /**
     * 1.转换流:属于字符流
     * InputStreamReader: 将一个字节的输入流转换为字符的输入流
     * OutputStreamReader: 将一个字符的输出流转换为字节的输出流
     * 2.作用:提供字节流与字符流之间的转换
     *
     * 3.解码:字节,字节数组 =》 字符,字符数组
     *   编码:字符,字符数组 =》 字节,字节数组
     *
     * 4,字符集
     */

    //字节的输入流到字符流的转换
    @Test
    public void test1() {
        FileInputStream fis = null;
        InputStreamReader inputStreamReader = null;
        try {
            fis = new FileInputStream(new File("D:\\test\\test1\\ha.txt"));
            //如果不填写字符编码,则会使用idea默认的字符编码,注意:这里的编码要和ha.txt文件保存时所用到的字符编码一致,要不然会出现乱码
            inputStreamReader = new InputStreamReader(fis,"UTF-8");
            char[] cbuff = new char[1024];
            int len;
            while ((len = inputStreamReader.read(cbuff)) != -1) {
                String str = new String(cbuff,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读入utf-8编码的txt,写出gbk编码的txt
    @Test
    public void test2() {
        InputStreamReader isR = null;
        OutputStreamWriter osW = null;
        try {
            FileInputStream fis = new FileInputStream(new File("D:\\test\\test1\\ha.txt"));
            FileOutputStream fos = new FileOutputStream(new File("D:\\test\\test1\\ha_gbk.txt"));
            //读写数据
            isR = new InputStreamReader(fis,"UTF-8");
            osW = new OutputStreamWriter(fos,"gbk");

            char[] cbuff = new char[1024];
            int len;
            while((len = isR.read(cbuff)) != -1) {
                osW.write(cbuff,0,len);

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

6.对象流的基本使用
1)Person类

package com.yl.pdfdemo.day08.p4;

import java.io.Serializable;

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description
 * @Version 1.0
 */

public class Person implements Serializable {
    /**
     * 注意:
     * Person需要满足以下要求,方可序列化
     * 1.需要实现Serializable接口
     * 2.当前类提供一个常量serialVersionUID
     * 3.除了当前Person类需要实现Serializable接口,还必须保证其内部属性也必须是系列化的,默认,基本数据类型可序列化
     *
     * ObjectInputStream,ObjectOutputStream不能序列化和反序列化static和transient修饰的成员变量
     */
    public static final long serialVersionUID = 1234354564667710L;
    private int age;
    private String name;
    private boolean male;

    public Person() {
    }

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

    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;
    }

    public boolean isMale() {
        return male;
    }

    public void setMale(boolean male) {
        this.male = male;
    }

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

2)测试

package com.yl.pdfdemo.day08.p4;
import org.junit.Test;

import java.io.*;

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description 对象流
 * @Version 1.0
 */

public class ObjectInputStreamTest {
    /**
     * ObjectInputStream,ObjectOutputStream
     * 作用:用于存储和读取基本数据类型数据或对象的处理流,它的强大之处在于可以把java的对象写入到数据源中,
     *      也能把对象从数据源中还原回来
     *
     *  序列化: 用ObjectOutputStream类保存基本数据类型或者对象的机制
     *  反序列化:用ObjectInputStream类读取基本数据类型或对象的机制
     *  ObjectInputStream,ObjectOutputStream不能序列化和反序列化static和transient修饰的成员变量
     *
     */

    //序列化过程: 将内存中的java对象保存到磁盘中,或者通过网络传输出去
    // 写出数据
    @Test
    public void test1() {
        ObjectOutputStream oos = null;
        try {
            //创建流
            oos = new ObjectOutputStream(new FileOutputStream("D:\\test\\test1\\object.dat"));
            //写数据
            oos.writeObject(new String("hellojavavue"));
            //刷新
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                //关闭流
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象
    //读数据
    @Test
    public void test2() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:\\test\\test1\\object.dat"));
            //读数据
            Object object = ois.readObject();
            String s = (String)object;
            System.out.println(s);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //自定义类实现序列化过程
    @Test
    public void test3() {
        ObjectOutputStream oos = null;
        try {
            //创建流
            oos = new ObjectOutputStream(new FileOutputStream("D:\\test\\test1\\object.dat"));
            //写数据
            oos.writeObject(new String("hellojavavue"));
            oos.writeObject(new Person(17,"小白",true));
            oos.writeObject(new Person(18,"小兰",false));
            //刷新
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                //关闭流
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //自定义类的反序列化过程
    @Test
    public void test4() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:\\test\\test1\\object.dat"));
            //读数据,按照存的顺序来取数据的
            Object object = ois.readObject();
            String s = (String)object;
            Object object1 = ois.readObject();
            Person p1 = (Person)object1;
            Object object2 = ois.readObject();
            Person p2 = (Person)object2;
            System.out.println(s);
            System.out.println(p1);
            System.out.println(p2);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

7.随机存储文件流的基本使用

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @Author wfj
 * @Date 2021/6/30
 * @Description
 * @Version 1.0
 */

public class RandomAccessFileTest {
    /**
     * RandomAccessFile继承了java.lang.Object类,实现了DataInput和DataOutput接口
     * 所以其既可以作为一个输入流,也可以作为一个输出流
     *  如果RandomAccessFile作为一个输出流,写出到的文件不存在,则在执行过程中自动创建
     *  如果写出到的文件存在,则会对原有文件内容进行覆盖,默认情况下,从头开始
     */

    //复制图片
    @Test
    public void test1() {
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            //第二个参数为模式,r代表可读,w代表可写
            raf1 = new RandomAccessFile(new File("D:\\test\\test1\\11.jpg"),"r");
            raf2 = new RandomAccessFile(new File("D:\\test\\test1\\r11.jpg"),"rw");
            byte[] bytes = new byte[1024];
            int len;
            while((len = raf1.read(bytes)) != -1) {
                raf2.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null) {
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (raf2 != null) {
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //使用RandomAccessFile实现数据的插入(比如我这里从第三个角标开始插入数据)
    @Test
    public void test2() {
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("D:\\test\\test1\\bb.txt","rw");
            raf1.seek(3);//将指针移到角标为3的位置
            //保存指针为3后的所有数据
            StringBuilder sb = new StringBuilder((int)new File("D:\\test\\test1\\bb.txt").length());
            byte[] bytes = new byte[1024];
            int len;
            while ((len = raf1.read(bytes)) != -1) {
                sb.append(new String(bytes,0,len));
            }
            raf1.seek(3);//调回指针
            raf1.write("zzz".getBytes());

            //写入sb中的数据
            raf1.write(sb.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null) {
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

8.其他流

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.*;

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description 其他的流
 * @Version 1.0
 */

public class OtherStreamTest {
    /**
     * 1.标准的输入输出流
     *  1.1
     *      System.in:标准的输入流(字节流),默认从键盘录入
     *      System.out:标准的输出流,默认从控制台输出
     *
     * 2.打印流(输出)
     *      PrintStream(字节流)
     *      PrintWriter(字符流)
     *
     * 3.数据流
     *      DataInputStream
     *      DataOutputStream
     *      作用:用于读取或写出基本数据类型的变量或字符串
     *
     */
    public static void main(String[] args) {
        BufferedReader bufferedReader = null;
        try {
            InputStreamReader isR = new InputStreamReader(System.in);
            bufferedReader = new BufferedReader(isR);

            while (true) {
                System.out.println("请输入字符串:");
                String data = bufferedReader.readLine();
                if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
                    System.out.println("程序结束");
                    break;
                }
                System.out.println(data.toUpperCase());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //打印流
    @Test
    public void test1() {
        PrintStream ps = null;
        try {
            FileOutputStream fos = new FileOutputStream(new File("D:\\test\\test1\\printTest.txt"));
            ps = new PrintStream(fos,true);
            if (ps != null) {
                System.setOut(ps);
            }

            //输出ASCII码
            for (int i = 0; i <= 255; i++) {
                System.out.print((char)i);
                if (i % 50 == 0) {
                    System.out.println();//每隔50个换行
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //写出数据
    @Test
    public void test2() {
        DataOutputStream dos = null;
        try {
            dos = new DataOutputStream(new FileOutputStream("D:\\test\\test1\\data.txt"));
            dos.writeUTF("小兰");
            dos.flush();//刷新,将内存中的数据写入到文件中
            dos.writeInt(17);
            dos.flush();
            dos.writeBoolean(true);
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读数据
    @Test
    public void test3() {
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new FileInputStream("D:\\test\\test1\\data.txt"));
            String s = dis.readUTF();
            int i = dis.readInt();
            boolean b = dis.readBoolean();
            System.out.println("name="+s);
            System.out.println("age="+i);
            System.out.println("isMale="+b);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

9.练习一:对图片进行加密,复制图片,再解密

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

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

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description 对图片进行加密和解密,原理,m ^ n ^ n = m
 * @Version 1.0
 */

public class PitctureTest {

    //图片加密
    @Test
    public void test1() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(new File("D:\\test\\test1\\11.jpg"));
            fos = new FileOutputStream(new File("D:\\test\\test1\\11q.jpg"));
            byte[] bytes = new byte[1024];
            int len;
            while((len = fis.read(bytes)) != -1) {
                //字节数组进行修改
                for (int i = 0; i < len; i++) {
                    bytes[i] = (byte)(bytes[i] ^ 5);
                }
                fos.write(bytes,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() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(new File("D:\\test\\test1\\11q.jpg"));
            fos = new FileOutputStream(new File("D:\\test\\test1\\qqqqq.jpg"));
            byte[] bytes = new byte[1024];
            int len;
            while((len = fis.read(bytes)) != -1) {
                //字节数组进行修改
                for (int i = 0; i < len; i++) {
                    bytes[i] = (byte)(bytes[i] ^ 5);
                }
                fos.write(bytes,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();
                }
            }
        }
    }
}

10.练习二:统计文本中每个字符出现的个数,使用Map来记录

package com.yl.pdfdemo.day08.p4;

import org.junit.Test;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Author wfj
 * @Date 2021/6/29
 * @Description 统计文本中每个字符出现的次数
 * @Version 1.0
 */

public class WordCountTest {

    @Test
    public void test1() {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(new File("D:\\test\\test1\\ha.txt")));
            bufferedWriter = new BufferedWriter(new FileWriter(new File("D:\\test\\test1\\wordCount.txt")));
            //记录每个字符出现的次数
            Map<Character,Integer> map = new HashMap<>();
            //一个一个字符的读取
            int len;
            while((len = bufferedReader.read()) != -1) {
                //强转为字符
                char c = (char)len;
                if (map.get(c) == null) {
                    map.put(c,1);
                } else {
                    map.put(c,map.get(c) + 1);
                }
            }

            //遍历map,往txt里写入数据
            Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
            for (Map.Entry<Character,Integer> entry : entrySet) {
                switch (entry.getKey()) {
                    case ' ':
                        bufferedWriter.write("空格=" + entry.getValue());
                        break;
                    case '\t':
                        bufferedWriter.write("tab键=" + entry.getValue());
                        break;
                    case '\r':
                        bufferedWriter.write("回车键=" + entry.getValue());
                        break;
                    case '\n':
                        bufferedWriter.write("换行=" + entry.getValue());
                        break;
                    default:
                        bufferedWriter.write(entry.getKey() + "=" + entry.getValue());
                        break;
                }
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值