JAVA基础:IO流 (学习笔记)

IO流

一,IO流的理解

i : input 输入

o:output 输入

流:方式,传递数据的方式---------相当于生活中的“管道”,“车”,将资源从一个位置,传递到另一个位置

二,IO流的分类

根据流的方向:输入流,输出流

根据流处理信息的大小: 字节流byte,字符流char

根据流的功能:节点流,处理流

  • IO流体系结构

三,使用流对象

  1. 获得数据源对象:
  2. 获得流对象同时链接数据源
  3. 读取数据:  ,---隐式打开水龙头
  4. 关闭!

         举个例子: 水资源,水管,====>打开水龙头,利用水管,来浇花!

四,File类

  • 在java程序中操纵 文件/目录 ?怎么办?

  1. java程序,最典型的特点,面向对象,java程序最擅长的就是操作对象,盘符上的文件/目录,将它的各种信息进行了封装,封装为一个对象,

  2. java程序最擅长的就是操纵对象,这个对象属于 ---》File类

  3. 读取文件/对文件进行操作

     public static void main1(String[] args) throws IOException {
            //1.获得数据源对象:
            File file=new File("E:\\dz15\\1.txt");
            //2.获得流对象,同时连接数据源:
            Reader fr=new FileReader(file);
            //3.读取:
            int number = fr.read();
            while(number!=-1){
                System.out.print((char)number);
                number=fr.read();
            }
            //4.关闭:
            fr.close();
        }
    
    
    //=========================================================================================
    public class Test01 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //将文件封装为一个File类的对象:
            File f = new File("d:\\test.txt");
            File f1 = new File("d:\\test.txt");
            File f2 = new File("d:/test.txt");
            //File.separator属性帮我们获取当前操作系统的路径拼接符号
           //在windows,dos下,系统默认用“\”作为路径分隔符 ,在unix,url中,使用“/”作为路径分隔符。
            File f3 = new File("d:"+File.separator+"test.txt");//建议使用这种
            //常用方法:
            System.out.println("文件是否可读:"+f.canRead());
            System.out.println("文件是否可写:"+f.canWrite());
            System.out.println("文件的名字:"+f.getName());
            System.out.println("上级目录:"+f.getParent());
            System.out.println("是否是一个目录:"+f.isDirectory());
            System.out.println("是否是一个文件:"+f.isFile());
            System.out.println("是否隐藏:"+f.isHidden());
            System.out.println("文件的大小:"+f.length());
            System.out.println("是否存在:"+f.exists());
            /*if(f.exists()){//如果文件存在,将文件删除操作
                f.delete();
            }else{//如果不存在,就创建这个文件
                f.createNewFile();
            }*/
            System.out.println(f == f1);//比较两个对象的地址
            System.out.println(f.equals(f1));//比较两个对象对应的文件的路径
            //跟路径相关的:
            System.out.println("绝对路径:"+f.getAbsolutePath());
            System.out.println("相对路径:"+f.getPath());
            System.out.println("toString:"+f.toString());
            System.out.println("----------------------");
            File f5 = new File("demo.txt");
            if(!f5.exists()){
                f5.createNewFile();
            }
            //绝对路径指的就是:真实的一个精准的,完整的路径
            System.out.println("绝对路径:"+f5.getAbsolutePath());
            //相对路径:有一个参照物,相对这个参照物的路径。
            //在main方法中,相对位置指的就是:D:\IDEA_workspace\TestJavaSE
            //在junit的测试方法中,相对路径指的就是模块位置
            System.out.println("相对路径:"+f5.getPath());
            //toString的效果永远是  相对路径
            System.out.println("toString:"+f5.toString());
            File f6 = new File("a/b/c/demo.txt");
            if(!f5.exists()){
                f5.createNewFile();
            }
            System.out.println("绝对路径:"+f6.getAbsolutePath());
            System.out.println("相对路径:"+f6.getPath());
        }
  4. 图片复制

     public static void main(String[] args) throws IOException {
    
            //1.获得数据源对象:
            File ifile= new File("D:\\1.png");
            File ofile=new File("E:\\1.png");
    
            //2.获得流对象同时连接数据源:
            InputStream is=new FileInputStream(ifile);
            OutputStream os=new FileOutputStream(ofile);
            //3.读取 同时 写入:
            byte[] bys=new byte[1024*8];
            int i=is.read(bys);
    
            int count=0;
            while(i!=-1){
                System.out.println("写入"+(++count));
                os.write(bys);
                i=is.read(bys);
            }
            //4.关闭: 先开的后关:
            os.close();
            is.close();
            System.out.println("复制完成!");
    
        }
  5. 对目录进行操作

    public class Test02 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) {
            //将目录封装为File类的对象:
            File f = new File("D:\\IDEA_workspace");
            System.out.println("文件是否可读:"+f.canRead());
            System.out.println("文件是否可写:"+f.canWrite());
            System.out.println("文件的名字:"+f.getName());
            System.out.println("上级目录:"+f.getParent());
            System.out.println("是否是一个目录:"+f.isDirectory());
            System.out.println("是否是一个文件:"+f.isFile());
            System.out.println("是否隐藏:"+f.isHidden());
            System.out.println("文件的大小:"+f.length());
            System.out.println("是否存在:"+f.exists());
            System.out.println("绝对路径:"+f.getAbsolutePath());
            System.out.println("相对路径:"+f.getPath());
            System.out.println("toString:"+f.toString());
            //跟目录相关的方法:
            File f2 = new File("D:\\a\\b\\c");【特殊强调,该目录不可以是隐藏目录!不然获得的file为null】
            //创建目录:
            //f2.mkdir();//创建单层目录
            //f2.mkdirs();//创建多层目录
            //删除:如果是删除目录的话,只会删除一层,并且前提:这层目录是空的,里面没有内容,如果内容就不会被删除
            f2.delete();
            //查看:
            String[] list = f.list();//文件夹下目录/文件对应的名字的数组
            for(String s:list){
                System.out.println(s);
            }
            System.out.println("=========================");
            File[] files = f.listFiles();//作用更加广泛
            for(File file:files){
                System.out.println(file.getName()+","+file.getAbsolutePath());
            }
        }

    例题:其实就是获取d:/ccjrjava文件夹及其子文件夹下的所有.java文件,使用readLine()读取其中每一行,每读取一行,行数加1。所有的文件读取完毕,得到总共已经写的Java代码行数。需要结合递归实现

    package ZongJie;
    
    import sun.reflect.generics.tree.VoidDescriptor;
    
    import java.io.*;
    
    public class Ccjrjava {
        private int count;//本类下调用
    
        //统计一个java文件的行数
        public void method2(File f1) throws IOException {
          //管道
                FileReader fr=new FileReader(f1);
                BufferedReader br=new BufferedReader(fr);
                while (br.readLine() != null){//判断每一行是否为空
                    count++;
                }
                br.close();
    
        }
    
       //统计文件夹中有多少Java文件
        public void method1(String str) throws IOException {
            //获取数据源
            File f1=new File(str);
            //判断是否存在
            if (!f1.exists()||!f1.isDirectory()){
                System.out.println("目录不存在");
                return;
            }
            //查看目录
            File[] f2 = f1.listFiles();//作用更加广泛
            for (int i = 0; i < f2.length; i++) {
                if (f2[i].isFile()){//判断是否是一个文件
                    if(f2[i].getName().toLowerCase().endsWith(".java")){
                  //判断文件名全转为小写后,尾部是不是”.java“
                        method2(f2[i]);//转至method2去判断文件内部
                    }
    
                }
                //递归统计代码行数
                if (f2[i].isDirectory()){
                    //准备统计的文件夹
                    String ss=f1+"\\\\"+f2[i].getName();
                    //得到文件夹后,再次重复判断其中的内容
                    method1(str);
                }
    
            }
    
    
        }
    
        public static void main(String[] args) throws IOException {
          //创建对象
            Ccjrjava ccjrjava=new Ccjrjava();
            ccjrjava.method1("D:\\dz\\ccjrjava");
            System.out.println(ccjrjava.count);
        }
    
    }
    

五,IO应用

  • 案例:通过JAVA完成文件的复制操作

  1. 功能分解1:文件--》程序:FileReader-----一个字符一个字符的将文件中的内容读取到程序中了:
    public class Test01 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //文件--》程序:
            //1.有一个文件:----》创建一个File类的对象
            File f = new File("d:\\Test.txt");
            //2.利用FileReader这个流,这个“管”怼到源文件上去   ---》创建一个FileReader的流的对象
            FileReader fr = new FileReader(f);
            //3.进行操作“吸”的动作  ---》读取动作
            /*下面的代码我们验证了:如果到了文件的结尾处,那么读取的内容为-1
            int n1 = fr.read();
            int n2 = fr.read();
            int n3 = fr.read();
            int n4 = fr.read();
            int n5 = fr.read();
            int n6 = fr.read();
            System.out.println(n1);
            System.out.println(n2);
            System.out.println(n3);
            System.out.println(n4);
            System.out.println(n5);
            System.out.println(n6);*/
            //方式1:
            /*int n = fr.read();
            while(n!=-1){
                System.out.println(n);
                n = fr.read();
            }*/
            //方式2:
            int n;
            while((n = fr.read())!=-1){
                System.out.println((char)n);
            }
            //4.“管”不用了,就要关闭  ---》关闭流
            //流,数据库,网络资源,靠jvm本身没有办法帮我们关闭,此时必须程序员手动关闭:
            fr.close();
        }
  2. 功能分解2:程序--》文件:FileWriter-----一个字符一个字符的向外输出
    public class Test03 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //1.有个目标文件:
            File f = new File("d:\\demo.txt");
            //2.FileWriter管怼到文件上去:
            FileWriter fw = new FileWriter(f);
            //3.开始动作:输出动作:
            //一个字符一个字符的往外输出:
            String str = "hello你好";
            for (int i = 0 ;i < str.length();i++){
                fw.write(str.charAt(i));
            }
            //4.关闭流:
            fw.close();
        }
    }
    
  3. 功能分解3:利用FileReader,FileWriter文件复制
    public class Test04 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //1.有一个源文件
            File f1 = new File("d:\\Test.txt");
            //2.有一个目标文件:
            File f2 = new File("d:\\Demo.txt");
            //3.搞一个输入的管 怼到源文件上:
            FileReader fr = new FileReader(f1);
            //4.搞一个输出的管,怼到目标文件上:
            FileWriter fw = new FileWriter(f2);
            //5.开始动作:
            //方式1:一个字符一个字符的复制:
            /*int n = fr.read();
            while(n!=-1){
                fw.write(n);   【】【写入一行内容同时换行 fw.write("123456"+"\n")】
                n = fr.read();
            }*/
            //方式2:利用缓冲字符数组:
            /*char[] ch = new char[5];
            int len = fr.read(ch);
            while(len!=-1){
                fw.write(ch,0,len);//将缓冲数组中有效长度写出
                len = fr.read(ch);
            }*/
            //方式3:利用缓冲字符数组,将数组转为String写出。
            char[] ch = new char[5];
            int len = fr.read(ch);
            while(len!=-1){
                String s = new String(ch,0,len);
                fw.write(s);
                len = fr.read(ch);
            }
            //6.关闭流:(关闭流的时候,倒着关闭,后用先关)
            fw.close();
            fr.close();
        }
    }
    
  • 利用try-catch-finally处理异常方式

    public class Test04 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args)  {
            //1.有一个源文件
            File f1 = new File("d:\\Test.txt");
            //2.有一个目标文件:
            File f2 = new File("d:\\Demo.txt");
            //3.搞一个输入的管 怼到源文件上:
            FileReader fr = null;
            FileWriter fw = null;
            try {
                fr = new FileReader(f1);
                //4.搞一个输出的管,怼到目标文件上:
                fw = new FileWriter(f2);
                //5.开始动作:
                char[] ch = new char[5];
                int len = fr.read(ch);
                while(len!=-1){
                    String s = new String(ch,0,len);
                    fw.write(s);
                    len = fr.read(ch);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //6.关闭流:(关闭流的时候,倒着关闭,后用先关)
                try {
                    if(fw!=null){//防止空指针异常
                        fw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(fr!=null){
                        fr.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
  •  FileInputStream读取文件中内容

  1.  读取文本文件:
    public class Test01 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //功能:利用字节流将文件中内容读到程序中来:
            //1.有一个源文件:
            File f = new File("D:\\Test.txt");
            //2.将一个字节流这个管 怼  到 源文件上:
            FileInputStream fis = new FileInputStream(f);
            //3.开始读取动作
            /*
            细节1:
            文件是utf-8进行存储的,所以英文字符 底层实际占用1个字节
            但是中文字符,底层实际占用3个字节。
            细节2:
            如果文件是文本文件,那么就不要使用字节流读取了,建议使用字符流。
            细节3:
            read()读取一个字节,但是你有没有发现返回值是 int类型,而不是byte类型?
            read方法底层做了处理,让返回的数据都是“正数”
            就是为了避免如果字节返回的是-1的话,那到底是读入的字节,还是到文件结尾呢。
             */
            int n = fis.read();
            while(n!=-1){
                System.out.println(n);
                n = fis.read();
            }
            //4.关闭流:
            fis.close();
        }
    }
  2. 利用字节流读取非文本文件:(以图片为案例:)--》一个字节一个字节的读取:
    public class Test02 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //功能:利用字节流将文件中内容读到程序中来:
            //1.有一个源文件:
            File f = new File("D:\\LOL.jpg");
            //2.将一个字节流这个管 怼  到 源文件上:
            FileInputStream fis = new FileInputStream(f);
            //3.开始读取动作
            int count = 0;//定义一个计数器,用来计读入的字节的个数
            int n = fis.read();
            while(n!=-1){
                count++;
                System.out.println(n);
                n = fis.read();
            }
            System.out.println("count="+count);
            //4.关闭流:
            fis.close();
        }
    }
    
  3. 利用字节类型的缓冲数组:
    public class Test03 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //功能:利用字节流将文件中内容读到程序中来:
            //1.有一个源文件:
            File f = new File("D:\\LOL.jpg");
            //2.将一个字节流这个管 怼  到 源文件上:
            FileInputStream fis = new FileInputStream(f);
            //3.开始读取动作
            //利用缓冲数组:(快递员的小车)
            byte[] b = new byte[1024*6];
            int len = fis.read(b);//len指的就是读取的数组中的有效长度
            while(len!=-1){
                //System.out.println(len);
                for(int i = 0;i<len;i++){
                    System.out.println(b[i]);
                }
                len = fis.read(b);
            }
            //4.关闭流:
            fis.close();
        }
    }
  •  FileInputStream,FileOutputStream完成非文本文件的复制

  1. 读入一个字节,写出一个字节:

    public class Test04 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //功能:完成图片的复制:
            //1.有一个源图片
            File f1 = new File("d:\\LOL.jpg");
            //2.有一个目标图片:
            File f2 = new File("d:\\LOL2.jpg");
            //3.有一个输入的管道 怼 到 源文件:
            FileInputStream fis = new FileInputStream(f1);
            //4.有一个输出的管道 怼到  目标文件上:
            FileOutputStream fos = new FileOutputStream(f2);
            //5.开始复制:(边读边写)
            int n = fis.read();
            while(n!=-1){
                fos.write(n);
                n = fis.read();
            }
            //6.关闭流:(倒着关闭流,先用后关)
            fos.close();
            fis.close();
        }
    }
    
  2. 利用缓冲字节数组:
    public class Test05 {
        //这是一个main方法,是程序的入口:
        public static void main(String[] args) throws IOException {
            //功能:完成图片的复制:
            //1.有一个源图片
            File f1 = new File("d:\\LOL.jpg");
            //2.有一个目标图片:
            File f2 = new File("d:\\LOL2.jpg");
            //3.有一个输入的管道 怼 到 源文件:
            FileInputStream fis = new FileInputStream(f1);
            //4.有一个输出的管道 怼到  目标文件上:
            FileOutputStream fos = new FileOutputStream(f2);
            //5.开始复制:(边读边写)
            //利用缓冲数组:
            byte[] b = new byte[1024*8];
            int len = fis.read(b);
            while(len!=-1){
                fos.write(b,0,len);
                len = fis.read(b);
            }
            //6.关闭流:(倒着关闭流,先用后关)
            fos.close();
            fis.close();
        }
    }
  • 缓冲字节流(处理流)-BufferedInputStream ,BufferedOutputStream

public class Test06 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.有一个源图片
        File f1 = new File("d:\\LOL.jpg");
        //2.有一个目标图片:
        File f2 = new File("d:\\LOL2.jpg");
        //3.有一个输入的管道 怼 到 源文件:
        FileInputStream fis = new FileInputStream(f1);
        //4.有一个输出的管道 怼到  目标文件上:
        FileOutputStream fos = new FileOutputStream(f2);
        //5.功能加强,在FileInputStream外面套一个管:BufferedInputStream:
        BufferedInputStream bis = new BufferedInputStream(fis);
        //6.功能加强,在FileOutputStream外面套一个管:BufferedOutputStream:
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //7.开始动作 :
        byte[] b = new byte[1024*6];
        int len = bis.read(b);
        while(len!=-1){
            bos.write(b,0,len);
           /* bos.flush(); 底层已经帮我们做了刷新缓冲区的操作,不用我们手动完成:底层调用flushBuffer()*/
            len = bis.read(b);
        }
        //8.关闭流:
        //倒着关:
        //如果处理流包裹着节点流的话,那么其实只要关闭高级流(处理流),那么里面的字节流也会随之被关闭。
        bos.close();
        bis.close();
        /*fos.close();
        fis.close();*/
    }
}
  • 比对非文本文件复制的三种方法的效率

public class Test06 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.有一个源图片
        File f1 = new File("d:\\LOL.jpg");
        //2.有一个目标图片:
        File f2 = new File("d:\\LOL2.jpg");
        //3.有一个输入的管道 怼 到 源文件:
        FileInputStream fis = new FileInputStream(f1);
        //4.有一个输出的管道 怼到  目标文件上:
        FileOutputStream fos = new FileOutputStream(f2);
        //5.功能加强,在FileInputStream外面套一个管:BufferedInputStream:
        BufferedInputStream bis = new BufferedInputStream(fis);
        //6.功能加强,在FileOutputStream外面套一个管:BufferedOutputStream:
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //7.开始动作 :
        long startTime = System.currentTimeMillis();
        byte[] b = new byte[1024];
        int len = bis.read(b);
        while(len!=-1){
            bos.write(b,0,len);
           /* bos.flush(); 底层已经帮我们做了刷新缓冲区的操作,不用我们手动完成:底层调用flushBuffer()*/
            len = bis.read(b);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("复制完成的时间为:"+(endTime-startTime));
        //8.关闭流:
        //倒着关:
        //如果处理流包裹着节点流的话,那么其实只要关闭高级流(处理流),那么里面的字节流也会随之被关闭。
        bos.close();
        bis.close();
        /*fos.close();
        fis.close();*/
    }
}
  • 缓冲字符流(处理流)-BufferedReader,BufferedWriter完成文本文件的复制

public class Test07 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.有一个源文件:
        File f1 = new File("d:\\Test.txt");
        //2.有一个目标文件:
        File f2 = new File("d:\\Demo.txt");
        //3.需要一个管 怼到 源文件:
        FileReader fr = new FileReader(f1);
        //4.需要一根管怼到目标文件:
        FileWriter fw = new FileWriter(f2);
        //5.套一根管在输入字符流外面:
        BufferedReader br = new BufferedReader(fr);
        //6.套一根管在输出字符流外面:
        BufferedWriter bw = new BufferedWriter(fw);
        //7.开始动作:
        //方式1:读取一个字符,输出一个字符:
        /*int n = br.read();
        while(n!=-1){
            bw.write(n);
            n = br.read();
        }*/
        //方式2:利用缓冲数组:
        /*char[] ch = new char[30];
        int len = br.read(ch);
        while(len!=-1){
            bw.write(ch,0,len);
            len = br.read(ch);
        }*/
        //方式3:读取String:
        String str = br.readLine();//每次读取文本文件中一行,返回字符串
        while(str!=null){
            bw.write(str);
            //在文本文件中应该再写出一个换行:
            bw.newLine();//新起一行
            str = br.readLine();
        }
        //8.关闭流
        bw.close();
        br.close();
    }
}
  • 转换流-InputStreamReader,OutputStreamWriter

public class Test01 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //文件---》程序:
        //1.有一个源文件:
        File f = new File("d:\\Test.txt");
        //2.需要一个输入的字节流接触文件:
        FileInputStream fis = new FileInputStream(f);
        //3.加入一个转换流,将字节流转换为字符流:(转换流属于一个处理流)
        //将字节转换为字符的时候,需要指定一个编码,这个编码跟文件本身的编码格式统一
        //如果编码格式不统一的话,那么在控制台上展示的效果就会出现乱码
        //InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        //获取程序本身的编码--》utf-8
        InputStreamReader isr = new InputStreamReader(fis);
        //4.开始动作,将文件中内容显示在控制台:
        char[] ch = new char[20];
        int len = isr.read(ch);
        while(len!=-1){
            //将缓冲数组转为字符串在控制台上打印出来
            System.out.print(new String(ch,0,len));
            len = isr.read(ch);
        }
        //5.关闭流:
        isr.close();
    }
}
  • 转换流-InputStreamReader,OutputStreamWriter实现文本文件的复制

public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.有一个源文件
        File f1 = new File("d:\\Test.txt");
        //2.有一个目标文件:
        File f2 = new File("d:\\Demo.txt");
        //3.输入方向:
        FileInputStream fis = new FileInputStream(f1);
        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        //4.输出方向:
        FileOutputStream fos = new FileOutputStream(f2);
        OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
        //5.开始动作:
        char[] ch = new char[20];
        int len = isr.read(ch);
        while(len!=-1){
            osw.write(ch,0,len);
            len = isr.read(ch);
        }
        //6.关闭流:
        osw.close();
        isr.close();
    }
}
  • System类对IO流的支持

public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        //写到控制台:
        PrintStream out = System.out;
        //调用方法:
        out.print("你好1");//直接在控制台写出,但是不换行
        out.print("你好2");
        out.print("你好3");
        out.print("你好4");
        out.println("我是中国人1");//直接在控制台写出,并且换行操作
        out.println("我是中国人2");
        out.println("我是中国人3");
        out.println("我是中国人4");
        System.out.println("你是");
        System.out.print("中国人");
    }
}
  • 练习:键盘录入内容输出到文件中

public class Test03 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.先准备输入方向:
        //键盘录入:
        InputStream in = System.in;//属于字节流
        //字节流--》字符流:
        InputStreamReader isr = new InputStreamReader(in);
        //在isr外面再套一个缓冲流:
        BufferedReader br = new BufferedReader(isr);
        //2.再准备输出方向:
        //准备目标文件
        File f = new File("d:\\Demo1.txt");
        FileWriter fw = new FileWriter(f);
        BufferedWriter bw = new BufferedWriter(fw);
        //3.开始动作:
        String s = br.readLine();
        while(!s.equals("exit")){
            bw.write(s);
            bw.newLine();//文件中换行
            s = br.readLine();
        }
        //4.关闭流:
        bw.close();
        br.close();
    }
}
  • 数据流-DataInputStream,DataOutputStream

数据流:用来操作基本数据类型和字符串

DataInputStream:将文件中存储的基本数据类型和字符串  写入  内存的变量中

DataOutputStream:  将内存中的基本数据类型和字符串的变量 写出  文件中

//输出
public class Test01 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //DataOutputStream:  将内存中的基本数据类型和字符串的变量 写出  文件中
        /*File f = new File("d:\\Demo2.txt");
        FileOutputStream fos = new FileOutputStream(f);
        DataOutputStream dos = new DataOutputStream(fos);*/
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File("d:\\Demo2.txt")));
        //向外将变量写到文件中去:
        dos.writeUTF("你好");
        dos.writeBoolean(false);
        dos.writeDouble(6.9);
        dos.writeInt(82);
        //关闭流:
        dos.close();
    }
}

//输入
public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //DataInputStream:将文件中存储的基本数据类型和字符串  写入  内存的变量中
        DataInputStream dis = new DataInputStream(new FileInputStream(new File("d:\\Demo2.txt")));
        //将文件中内容读取到程序中来:
        System.out.println(dis.readUTF());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readDouble());
        System.out.println(dis.readInt());
        //关闭流:
        dis.close();
    }
}
  • 对象流-ObjectInputStream,ObjectOutputStream

    1.对象流:ObjectInputStream,ObjectOnputStream

                     用于存储和读取基本数据类型数据或对象的处理流。

                    它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

  2.序列化和反序列化:
      (1)ObjectOutputStream 类 : 把内存中的Java对象转换成平台无关的二进制数据,从而允许把这种二进制数据持久地保存在磁盘上,或通过网络将这种二进制数据传输到另一个网络节点。----》序列化

      细节:

             被序列化的类的内部的所有属性,必须是可序列化的 (基本数据类型都是可序列化的)

             static,transient修饰的属性 不可以被序列化。

public class Person implements Serializable {
    private static final long serialVersionUID = 8027651838638826533L;
    private transient String name;
    private static int age;
    private Famaily f = new Famaily();
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person() {
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", f=" + f + ",age=" + age +
                '}';
    }
}

public class Test01 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\Demo3.txt")));
        //将内存中的字符串写出到文件中:
        oos.writeObject("你好");
        //关闭流:
        oos.close();
    }
}

       (2)  用ObjectInputStream类 : 当其它程序获取了这种二进制数据,就可以恢复成原来的Java对象。----》反序列化
public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //将文件中保存的字符串 读入到 内存:
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\Demo3.txt")));
        //读取:
        String s = (String)(ois.readObject());
        System.out.println(s);
        //关闭流:
        ois.close();
    }
}

    3.操作自定义类的对象
    4 序列号:.serialVersionUID

 

 

alt+enter: 回车 即可生成序列号

自定义类
public class Person implements Serializable {
    private static final long serialVersionUID = 8027651838638826533L;
    private transient String name;
    private static int age;
    private Famaily f = new Famaily();
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person() {
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", f=" + f + ",age=" + age +
                '}';
    }
}
测试类
public class Test01 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //序列化:将内存中对象 ---》 文件:
        //有一个对象:
        Person p = new Person("lili",19);
        //有对象流:
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\Demo4.txt")));
        //向外写:
        oos.writeObject(p);
        //关闭流:
        oos.close();
    }
}

反序列化
public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\Demo4.txt")));
        //读入内存:
        Person p = (Person)(ois.readObject());
        System.out.println(p/*.toString()*/);
        //关闭流:
        ois.close();
    }
}

文本文件:.txt   .java  .c  .cpp  ---》建议使用字符流操作
非文本文件:.jpg,  .mp3  ,   .mp4 , .doc  , .ppt  ---》建议使用字节流操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/902154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从0开始深度学习(16)——暂退法(Dropout)

上一章的过拟合是由于数据不足导致的&#xff0c;但如果我们有比特征多得多的样本&#xff0c;深度神经网络也有可能过拟合 1 扰动的稳健性 经典泛化理论认为&#xff0c;为了缩小训练和测试性能之间的差距&#xff0c;应该以简单的模型为目标&#xff0c;即模型以较小的维度的…

Qt中使用线程之QConcurrent

QConcurrent可以实现并发&#xff0c;好处是我们可以不用单独写一个类了&#xff0c;直接在类里面定义任务函数&#xff0c;然后使用QtConcurrent::run在单独的线程里执行一个任务 1、定义一个任务函数 2、定义1个QFutureWatcher的对象&#xff0c;使用QFutureWatcher来监测任…

新手直播方案

简介 新手直播方案 &#xff0c;低成本方案 手机/电脑 直接直播手机软件电脑直播手机采集卡麦电脑直播多摄像机 机位多路采集卡 多路麦加电脑&#xff08;高成本方案&#xff09; 直播推流方案 需要摄像头 方案一 &#xff1a;手机 电脑同步下载 网络摄像头 软件&#xff08…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

小程序开发实战:PDF转换为图片工具开发

目录 一、开发思路 1.1 申请微信小程序 1.2 编写后端接口 1.3 后端接口部署 1.4 微信小程序前端页面开发 1.5 运行效果 1.6 小程序部署上线 今天给大家分享小程序开发系列&#xff0c;PDF转换为图片工具的开发实战&#xff0c;感兴趣的朋友可以一起来学习一下&#xff01…

linux中级(NFS服务器)

NFS&#xff1a;用于在NNIX/Linux主机之间进行文件共享的协议 流程&#xff1a;首先服务端开启RPC服务&#xff0c;并开启111端口&#xff0c;服务器端启动NFS服务&#xff0c;并向RPC注册端口信息&#xff0c;客户端启动RPC&#xff0c;向服务器RPC服务请求NFS端口&#xff0…

anaconda 创建环境失败 解决指南

anaconda 创建环境失败 解决指南 一、问题描述 我在宿舍有一台电脑。由于我经常泡在实验室&#xff0c;所以那台电脑不是经常用&#xff0c;基本吃灰。昨天晚上突然有在那台电脑上使用Camel-AI部署多智能体协同需求&#xff0c;便戳开了电脑&#xff0c;问题也随之而来。 当…

汽车级DC-DC转换器英飞凌TLF35584

上汽荣威都在用的汽车级DC-DC转换器英飞凌TLF35584 今天平台君从IPBrain数据库中给大家带来的一款由Infineon(英飞凌)推出的一款多路输出安全电源芯片,具备高可靠性和安全性。适用于汽车电子系统中的多种应用场景,如车身控制、安全气囊、防抱死制动系统,电子稳定控制系统等。…

设计模式基础知识以及典型设计模式总结(上)

1. 基础 1. 什么是设计模式&#xff1f; 设计模式是指在软件开发中&#xff0c;经过验证的&#xff0c;用于解决在特定环境下重复出现的特定问题的解决方案。 简单的说&#xff0c;设计模式是解决问题的固定套路。 慎用设计模式。 2. 设计模式是怎么来的&#xff1f; 满足…

Unity3D学习FPS游戏(4)重力模拟和角色跳跃

前言&#xff1a;前面两篇文章&#xff0c;已经实现了角色的移动和视角转动&#xff0c;但是角色并没有办法跳跃&#xff0c;有时候还会随着视角移动跑到天上。这是因为缺少重力系统&#xff0c;本篇将实现重力和角色跳跃功能。觉得有帮助的话可以点赞收藏支持一下&#xff01;…

fmql之Linux RTC

模拟i2c&#xff0c;连接rtc芯片。 dts&#xff1a; /{ // 根节点i2c_gpio: i2c-gpio {#address-cells <1>;#size-cells <0>;compatible "i2c-gpio";// MIO56-SDA, MIO55-SCL // 引脚编号gpios <&portc 2 0&portc 1 0 >;i2c-gp…

Unity3D学习FPS游戏(2)简单场景、玩家移动控制

前言&#xff1a;上一篇的时候&#xff0c;我们已经导入了官方fps的素材&#xff0c;并且对三维模型有了一定了解。接下来我们要构建一个简单的场景让玩家能够有地方移动&#xff0c;然后写一个简单的玩家移动控制。 简单场景和玩家移动 简单场景玩家移动控制玩家模型视野-摄像…

单细胞配色效果模拟器 | 简陋版(已有颜色数组)

目的&#xff1a;假设你有一组颜色了&#xff0c;怎么模拟查看它们在单细胞DimPlot中的美学效果呢&#xff1f;要足够快&#xff0c;还要尽可能有模拟效果。 1. 尝试1: 随机矩阵&#xff0c;真的UMAP降维后绘图&#xff08;失败&#xff09; 造一个随机矩阵&#xff0c;使用S…

华为鸿蒙HarmonyOS应用开发者高级认证视频及题库答案

华为鸿蒙开发者高级认证的学习资料 1、课程内容涵盖HarmonyOS系统介绍、DevEco Studio工具使用、UI设计与开发、Ability设计与开发、分布式特性、原子化服务卡片以及应用发布等。每个实验都与课程相匹配&#xff0c;帮助加深理解并掌握技能 2、学习视频资料 华为HarmonyOS开发…

全能大模型GPT-4o体验和接入教程

GPT-4o体验和接入教程 前言一、原生API二、Python LangchainSpring AI总结 前言 Open AI发布了产品GPT-4o&#xff0c;o表示"omni"&#xff0c;全能的意思。 GPT-4o可以实时对音频、视觉和文本进行推理&#xff0c;响应时间平均为 320 毫秒&#xff0c;和人类之间对…

动态规划 —— 斐波那契数列模型-解码方法

1. 解码方法 题目链接&#xff1a; 91. 解码方法 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/decode-ways/description/ 2. 题目解析 1. 对字母A - Z进行编码1-26 2. 11106可以解码为1-1-10-6或者11-10-6, 但是11-1-06不能解码 3. 0n不能解码 4. …

微知-Lecroy力科的PCIe协议分析仪型号命名规则(PCIe代,金手指lanes数量)

文章目录 要点主要型号命名规则各代主要产品图片Summit M616 协议分析仪/训练器Summit T516 分析仪Summit T416 分析仪Summit T3-16分析仪Summit T28 分析仪 综述 要点 LeCroy(力科)成立于1964年&#xff0c;是一家专业生产示波器厂家。在美国纽约。一直把重点放在研制改善生产…

【Linux】线程池详解及其基本架构与单例模式实现

目录 1.关于线程池的基本理论 1.1.线程池是什么&#xff1f; 1.2.线程池的应用场景&#xff1a; 2.线程池的基本架构 2.1.线程容器 2.2.任务队列 2.3.线程函数&#xff08;HandlerTask&#xff09; 2.4.线程唤醒机制 3.添加单例模式 3.1.单例模式是什么&…

【Canvas与图标】六色彩虹圆角六边形图标

【成图】 120*120的png图标 以下是各种大小图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>六色彩虹圆角六边形…

总裁主题CeoMax-Pro主题7.6开心版

激活方式&#xff1a; 1.授权接口源码ceotheme-auth-api.zip搭建一个站点&#xff0c;绑定www.ceotheme.com域名&#xff0c;并配置任意一个域名的 SSL 证书。 2.在 hosts 中添加&#xff1a;127.0.0.1 www.ceotheme.com 3.上传class-wp-http.php到wp-includes目录&#xff…