• Java IO学习笔记


    Java流的分类,一般可按以下方式分:

    1. 按方向分,分为输入流,输出流。
    2. 按类型分,分为字节流和字符流。
      2.1字节流是通过字节来读取数据
      2.2字符流是通过字符来读取数据
    3. 按操作方式分,分为节点流和过滤流。
      3.1 可以直接创建的流称为节点流,比如输入流,输出流
      3.2 过滤流可以装饰节点流,让流的功能变得更加强大,过滤流采用装饰者模式,对输入流进行包装。比如说BufferedInputStream,BufferedOutputStream,DataInputStream,DataOutputStream都是过滤流。
    4. 转换流。

    废话不多说,看代码:
    使用字节流读取文件内容:

        public void test1(){
            File file = new File("F:\hello.txt");
            FileInputStream fis = null;
            try {
                //创建一个文件输入流
                fis = new FileInputStream(file);
                //创建一个字节数组用来存储读取的信息
                byte[] buf = new byte[1024];
                //len表示读取的长度
                int len = 0;
                //只要len大于-1说明读取到元素,可对元素直接进行操作
                while((len=fis.read(buf))>-1){
                    //通过控制台输出程序,需要指明输出的长度
                    System.out.write(buf,0,len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if (fis!=null) {
                        //操作完成之后关闭流
                        fis.close();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    如何通过操作字节流来实现简单的文件拷贝呢?使用未经包装的输入输出流来拷贝文件,看代码:

        public void test2(){
            long startTime = new Date().getTime();
            File file = new File("F:\mysql-installer-community-5.6.22.0.msi");
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                fis = new FileInputStream(file);
                fos = new FileOutputStream("F:\1.msi");
                byte[] buf = new byte[1024];
                int len = 0;
                while((len=fis.read(buf))!=-1){
                    fos.write(buf, 0, len);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(fis!=null) fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(fos!=null) fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            long endTime = new Date().getTime();
            //查看效率
            System.out.println((endTime-startTime)/1000);
        }

    最后的输出结果为2,也就是说拷贝一个接近300M的文件需要两秒钟。

    再看看经过BufferedInputStream和BufferedOutputStream包装后的相同文件的拷贝,代码如下:

        public void test3(){
            long startTime = new Date().getTime();
            File file = new File("F:\mysql-installer-community-5.6.22.0.msi");
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                fis = new FileInputStream(file);
                //将fis包装起来
                bis = new BufferedInputStream(fis);
                //将输出流包装
                bos = new BufferedOutputStream(new FileOutputStream("F:\2.msi"));
                byte[] buf = new byte[1024];
                int len = 0;
                while((len=bis.read(buf))!=-1){
                    bos.write(buf, 0, len);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                //关闭流之后会自动flush
                try {
                    if(bis!=null) bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(bos!=null) bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            long endTime = new Date().getTime();
            System.out.println((endTime-startTime)/1000);
        }

    这里的输出为0,也就是说相同的文件拷贝,包装后的流效率会大大提高,原先需要两秒才能完成的拷贝,现在1秒都不到。

    再看DataInputStream和DataOutputStream,这两个依然是将InputStream流包装,包装完成之后可以用它写基本类型数据以及字符型数据。

        public void test4(){
            FileOutputStream fos = null;
            DataOutputStream dos = null;
            DataInputStream dis = null;
            try {
                fos = new FileOutputStream("F:\2.txt");
                dos = new DataOutputStream(fos);
                /**
                 * 每写一个Int类型数据,相当于写入四个字节数据,占四个字节,long是八个字节
                 * 依次类推
                 */
                dos.writeInt(1111);
                dos.writeInt(2222);
                dos.writeInt(3333);
                dis = new DataInputStream(new FileInputStream("F:\2.txt"));
                /**
                 * 每执行一次readInt(),相当于读取四个字节数据,读取其他数据依次类推
                 */
                System.out.println(dis.readInt());
                System.out.println(dis.readInt());
                System.out.println(dis.readInt());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(dos!=null) dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(dis!=null) dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    再看看包装后的字符流输入与输出:

        public void test5(){
            BufferedReader br = null;
            PrintWriter out = null;
            try {
                br = new BufferedReader(new FileReader("F:\hello.txt"));
                out = new PrintWriter(new BufferedWriter(new FileWriter("F:\11.txt")));
                String str = null;
                while((str=br.readLine())!= null){
                    System.out.println(str);
                    out.println(str);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(br!=null) br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(out!=null) out.close();
            }
        }

    字节流和字符流之间的转换,可以使用
    字符流 =InputStreamReader(字节流)

    把从控制台输入的文本内容转存到文本当中:

        public void test6() {
            BufferedReader br = null;
            PrintWriter out = null;
            try {
                br = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(new BufferedWriter(new FileWriter(
                        "F:\222.txt")));
                String str = null;
                while ((str = br.readLine()) != null) {
                    if (str.trim().equals("exit")) {
                        break;
                    }
                    System.out.println(str);
                    out.println(str);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (br != null)
                        br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (out != null)
                    out.close();
            }
        }

    把一个对象写入到文件中:

        public void writeObject(){
            User user = new User("zhangsan","123");
            user.setMoney(200);
            ObjectOutputStream oos = null;
            try {
                oos = new ObjectOutputStream(new FileOutputStream("F:\object.dat"));
                oos.writeObject(user);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(oos!=null) oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    User.java

    import java.io.Serializable;
    
    public class User implements Serializable{
    
        private String username;
        private String password;
    
        //添加了transient属性的字段不会被存储
        private transient int money;
    
    
    
        public int getMoney() {
            return money;
        }
        public void setMoney(int money) {
            this.money = money;
        }
        public User() {
        }
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }

    从文件中读取一个对象:

        public void readObject(){
            ObjectInputStream ois = null;
            try {
                ois = new ObjectInputStream(new FileInputStream("F:\object.dat"));
                User u = (User) ois.readObject();
                System.out.println(u.getUsername()+","+u.getPassword()+","+u.getMoney());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    输出结果是:
    这里写图片描述

    由于给money字段添加了transient属性,所以money字段并不会被存储,当然也就读取不到。如果在User.java中删除transient,那么输出结果就是:

    这里写图片描述

    这个时候money就可被顺利的读取出来。

  • 相关阅读:
    curl 设置超时时间
    allure 2
    shell 给文件每一行都添加指定字符串
    shell 文件的包含
    shell 求数组的平均值,求和,最大值,最小值
    shell 编写进度条
    shell 换行与不换行
    Linux常用命令简述--dirname与basename
    shell中脚本参数传递getopts
    Shell 中eval的用法
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461878.html
Copyright © 2020-2023  润新知