IO 输入输出流

声明:以下笔记来源于韩顺平视频https://www.bilibili.com/video/BV1fh411y7R8?p=1,笔记为楼主亲手劳动,劳动不易,转载请标明谢谢。

IO 流

创建文件对象相关构造器和方法
  1. new File(String pathname) //根据路径构建一个File对象

  2. new File(File parent,String child) //根据父目录文件+子路径构建

  3. new File(String parent,String child) //根据父目录+子路径构建

  4. public class FileCreate {
     public static void main(String[] args) {
     }
    
    
     @Test
     public void create01() {
         String filePath = "d:\\test\\news1.txt";
         File file = new File(filePath);
         try {
             file.createNewFile();
             System.out.println("文件创建成功!");
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
    
     @Test
     public void create02() {
         File parentFile = new File("d:\\test");
         String fileName = "news02.txt";
         File file = new File(parentFile, fileName);
         try {
             file.createNewFile();
             System.out.println("文件创建成功!");
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
    
     @Test
     public void create03() {
         String parentFile = "d:\\test";
    //        String parentFile = "d:/test";
         String fileName = "news02.txt";
         File file = new File(parentFile, fileName);
         try {
             file.createNewFile();
             System.out.println("文件创建成功!");
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
    }
    
  5. 常用方法

    • getName、getAbsolutePath, getParent、 length、 exists、 isFile、isDirectory

    • public class FileInformation {
       public static void main(String[] args) {
       }
      
       @Test
       public void info() {
           //getName、getAbsolutePath, getParent、 length、 exists、 isFile、isDirectory
           File file = new File("d:\\test\\news1.txt");
           System.out.println(file.getName());//获取文件名字
           System.out.println(file.getAbsolutePath());//获取文件绝对路径
           System.out.println(file.getParent());//获取文件父目录
           System.out.println(file.length());//获取文件大小
           System.out.println(file.exists());//获取是否存在
           System.out.println(file.isFile());//获取是否是文件
           System.out.println(file.isDirectory());//获取是否是目录
       }
      }
      
目录的操作与文件的删除
  1. mkdir创建一-级目录、mkdirs 创建多级目录、delete删除空目录或文件

  2. public class Directory_ {
     public static void main(String[] args) {
     }
    
     @Test
     public void m1() {
         File file = new File("d:\\test\\news1.txt");
         if (file.exists()) {
             if (file.delete()) {
                 System.out.println("文件删除成功");
             }else {
                 System.out.println("文件删除失败");
             }
         }else {
             System.out.println("文件不存在");
         }
     }
    
     @Test
     public void m2() {//目录可以被当做文件
         File file = new File("d:\\test");
         if (file.exists()) {
             if (file.delete()) {
                 System.out.println("目录删除成功");
             }else {
                 System.out.println("目录删除失败");
             }
         }else {
             System.out.println("目录不存在");
         }
     }
    
     @Test
     public void m3() {//目录可以被当做文件
         String directoryPath = "d:\\test\\demo\\a\\b\\c";
         File file = new File(directoryPath);
         if (file.exists()) {//exists 创建多级目录 exist创建一级目录 d:\test
             System.out.println(directoryPath + "存在");
         }else {
             if (file.mkdirs()) {
                 System.out.println(directoryPath + "创建成功");
             } else {
                 System.out.println(directoryPath + "创建失败");
             }
         }
     }
    }
    
IO 流原理及流的分类
  1. 按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)文本文件

  2. 按数据流的流向不同分为:输入流,输出流

  3. 按流的角色的不同分为:节点流,处理流/包装流

  4. (抽象基类)字节流字符流
    输入流InputStreamReader
    输出流OutputStreamWriter
  5. Java的IO流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的。

  6. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

FileInputStream
  1. FileInputStream:文件输入流

  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NikFX9UE-1648481509836)(D:/Typora%20Data/Img/image-20220317185810899.png)]

  3. public class FileInputStream_ {
     public static void main(String[] args) {
     }
    
     @Test
     public void readFile01() {
         String filePath = "d:\\test\\news1.txt";
         int readData = 0;
         FileInputStream fileInputStream = null;
         try {
             fileInputStream = new FileInputStream(filePath);
             while ((readData = fileInputStream.read()) != -1) {
                 System.out.print((char) readData);
             }
         } catch (IOException e) {
             e.printStackTrace();
         }finally {
             try {//一定要记得释放资源
                 fileInputStream.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
    
     @Test
     public void readFile02() {
         String filePath = "d:\\test\\news1.txt";
         byte[] buf = new byte[8];
         int len = 0;
         FileInputStream fileInputStream = null;
         try {
             fileInputStream = new FileInputStream(filePath);
             while ((len = fileInputStream.read(buf)) != -1) {
                 System.out.print(new String(buf, 0,len));
             }
         } catch (IOException e) {
             e.printStackTrace();
         }finally {
             try {//一定要记得释放资源
                 fileInputStream.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
    }
    
FileOutputStream
  1. FileOutputStream:文件输出流

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ny4L7OJJ-1648481509842)(D:/Typora%20Data/Img/image-20220318091240284.png)]

  2. public class FileOutputStream_ {
    public static void main(String[] args) {
    }
    
    @Test
    public void writeFile() {
      String filePath = "d:\\test\\news1.txt";
      FileOutputStream fileOutputStream = null;
      try {
    //            fileOutputStream = new FileOutputStream(filePath);
          fileOutputStream = new FileOutputStream(filePath,true);
    //            fileOutputStream.write('H');
          String str = "hello,world";
          fileOutputStream.write(str.getBytes(),0,5);
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          try {
              fileOutputStream.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
    }
    }
    
节点流与处理流
  1. 节点流可以从一个特定的数据源读写数据,如FileReader、 FileWriter (就是只能处理单个数据源的)

  2. 处理流(也叫包装流)是"连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter (修饰器设计模式 ↓)

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KE5Tpmv0-1648481509844)(D:/Typora%20Data/Img/image-20220318102806343.png)]

  3. BufferedReader 测试代码

    • public class BufferedWriter_ {
      public static void main(String[] args) throws Exception{
        String filePath = "D:\\test\\news1.txt";
        BufferedReader reader = new BufferedReader(new FileReader(filePath));
        String line;
        while ((line = reader.readLine()) != null){
            System.out.println(line);
        }
        reader.close();
      }
      }
      
  4. BufferedWriter 测试代码

    • public class BufferWriter_ {
      public static void main(String[] args) throws Exception{
        String filePath = "D:\\test\\news2.txt";
        //包装类 BufferedWriter 没有提供 append的构造方法 ,在底层流可以添加
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
        bufferedWriter.write("test bufferedWriter!!!");
        bufferedWriter.newLine();//根据系统自动插入换行符
        bufferedWriter.write("test bufferedWriter!!!");
        bufferedWriter.newLine();
        bufferedWriter.write("test bufferedWriter!!!");
        bufferedWriter.newLine();
        bufferedWriter.write("test bufferedWriter!!!");
        bufferedWriter.close();
      }
      }
      
BufferedInputStream:缓冲字节输入流
  1. BufferedInputStream是字节流在创建BufferedInputStream时,会创建一个内部缓冲区数组.

  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqT3Miuk-1648481509844)(D:/Typora%20Data/Img/image-20220318160811562.png)]

  3. 相关代码

    • public class BufferedCopy02 {
       public static void main(String[] args) {
           String srcPath = "D:\\Program Files\\韩顺平 2021零基础学Java 【软件 资料 代码 笔记】\\资料\\分享资料\\bg.png";
           String destPath = "D:\\test\\bg.png";
           BufferedInputStream bis = null;
           BufferedOutputStream bos = null;
           try {
               bis = new BufferedInputStream(new FileInputStream(srcPath));
               bos = new BufferedOutputStream(new FileOutputStream(destPath));
               byte[] data = new byte[1024];
               int readLen;
               while ((readLen = bis.read(data)) != -1) {
                   bos.write(data,0,readLen);
               }
      
           } catch (IOException e) {
               e.printStackTrace();
           } finally {
               try {
                   bis.close();
                   bos.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
      }
      
BufferedOutputStream:缓冲字节输出流

BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qF55CrRA-1648481509845)(D:/Typora%20Data/Img/image-20220318160425843.png)]

ObjectInputStream 与 ObjectOutputStream(两个都是包装流)

处理流(包装流)使用了修饰器设计模式

序列化和反序列化

  1. 序列化就是在保存数据时,保存数据的值和数据类型

  2. 反序列化就是在恢复数据时,恢复数据的值和数据类型

  3. 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之 一 :

    • Serializable//这是一个标记接口,没有方法
    • Externalizable //该接口有方法需要实现,因此我们一般实现上面的Serializable接口
  4. ObjectOutputStream提供序列化功能

  5. ObjectInputStream提供反序列化功能

  6. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sMMYyPrv-1648481509847)(D:/Typora%20Data/Img/image-20220318170611230.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFyKhz3i-1648481509848)(D:/Typora%20Data/Img/image-20220318170711686.png)]

  7. 相关练习代码

    • public class ObjectOutputStream_ {//写出是序列化
       public static void main(String[] args) throws Exception{
           String filePath = "d:\\test\\data.dat";
           ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
      
           oos.writeInt(100);
           oos.writeBoolean(true);
           oos.writeChar('a');
           oos.writeDouble(9.5);
           oos.writeUTF("UTF 表示一个字符串");
           oos.writeObject(new Dog("旺财",5));
           oos.close();
           System.out.println("序列化保存对象流");
       }
      }
      
      class Dog implements Serializable {
       private String name;
       private int age;
      
       public Dog(String name, int age) {
           this.name = name;
           this.age = age;
       }
      }
      
      public class ObjectInputStream_ {//读入是反序列化
       public static void main(String[] args) throws Exception {
           String filePath = "d:\\test\\data.dat";
           ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
           //获取要一一对应文件里面的类型
           System.out.println(ois.readInt());
           System.out.println(ois.readBoolean());
           System.out.println(ois.readChar());
           System.out.println(ois.readDouble());
           System.out.println(ois.readUTF());
           Object object = ois.readObject();
           System.out.println(object);
           System.out.println("object 的类型" + object.getClass());
           ois.close();
      
       }
      }
      
  8. 注意事项与细节

      1. 读写顺序要一致

      2. 要求序列化或反序列化对象,需要实现 Serializable

      3. 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性

        • private static final long serialVersionUID = 1L;
          
      4. 序列化对象时,默认将里面所有属性都进行序列化,但除了statictransient修饰的成员

      5. 序列化对象时,要求里面属性的类型也需要实现序列化接口.

      6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

FileReader
  1. 类图

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DnTXnOzj-1648481509849)(D:/Typora%20Data/Img/image-20220318091132551.png)]

  2. 相关方法

    1. new FileReader(File/String)
      read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
      read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
      new String(char[]):将char[]转换成String
      new String(char[],off,len):将char]的指定部分转换成Strin
  3. 测试代码

    • public class FileReader_ {
       public static void main(String[] args) {
       }
      
       @Test
       public void readerFile02() {
           String filePath = "D:\\test\\news1.txt";
           FileReader fileReader = null;
           int data ;
           try {
               fileReader = new FileReader(filePath);
               while ((data = fileReader.read()) != -1) {
                   System.out.print((char)data);
               }
           } catch (IOException e) {
               e.printStackTrace();
           }finally {
               try {
                   fileReader.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
      
       @Test
       public void readerFile01() {
           String filePath = "D:\\test\\news1.txt";
           FileReader fileReader = null;
           char[] data = new char[8];
           int readlen;
           try {
               fileReader = new FileReader(filePath);
               while ((readlen = fileReader.read(data)) != -1) {
                   System.out.print(new String(data,0,readlen));
               }
           } catch (IOException e) {
               e.printStackTrace();
           }finally {
               try {
                   fileReader.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
      }
      
FileWriter
  1. 类图

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fhd520Aa-1648481509849)(D:/Typora%20Data/Img/image-20220318091633915.png)]

  2. 常用方法

      1. new FileWriter(File/String):覆盖模式,相当于流的指针在首端
      2. new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
      3. write(int):写入单个字符
      4. write(char[]):写入指定数组
      5. write(char[],off,len):写入指定数组的指定部分
      6. write (string) :写入整个字符串
      7. write(string,of,len):写入字符串的指定部分
      8. 相关API: String类: toCharArray:将String转换成char[]
      9. FileWriter使用后,必须要关闭(close)或刷新(flush), 否则写入不到指定的文件(应该是包括Writer及其子类都要flush)!
  3. 测试代码

    • public class FileWriter_ {
       public static void main(String[] args) {
       }
      
       @Test
       public void writerFile01() {
           String filePath = "D:\\test\\news1.txt";
           FileWriter fileWriter = null;
           char[] data = {'a','b','c'};
           try {
               fileWriter = new FileWriter(filePath);
               fileWriter.write('H');
               fileWriter.write(data);
               fileWriter.write("字符窜测试".toCharArray(),0,3);
               fileWriter.write("霓虹啊");
               fileWriter.write("霓虹啊",0,1);
           } catch (IOException e) {
               e.printStackTrace();
           } finally {
               try {
                   fileWriter.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
      
      }
      
标准输入输出流
//System 类的pubLic final static InputStream in = null;
// System.in 编译类型
InputStream 
// System.in 运行类型
BufferedInputStream
//表示的是标准输入键盘
System.out.printLn(System.in.getCLass());


//1. System.out pubLic final static PrintStream out = nuLL;
//2. 编译类型PrintStream
//3. 运行类型PrintStream
//4. 表示标准输出显示器
System.out.printLn(System.out.getClass());
转换流 InputStreamReader与 OutputStreamWriter
    1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)
    2. OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
    3. 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
    4. 可以在使用时指定编码格式(比如utf -8, gbk,gb2312, IS08859-1等)
  1. 类图

    • InputStreamReader

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PiEwF6Zg-1648481509850)(D:/Typora%20Data/Img/image-20220319094110901.png)]

      OutputStreamWriter

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-10zs5VAP-1648481509851)(D:/Typora%20Data/Img/image-20220319094229977.png)]

  2. 案例

    • public class InputStreamReader_ {
       public static void main(String[] args) throws IOException {
           String filePath = "d:\\test\\news3.txt";
           BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));
                   reader.close();
           System.out.println("转换流读取=" + reader.readLine());
       }
      }
      
      public class OutputStreamWriter_ {
       public static void main(String[] args) throws IOException {
           String filePath = "d:\\test\\news2.txt";
           String charSet = "utf8";
           OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
           isr.write("hi,输出装换流");
           isr.close();
           System.out.println(charSet + "转换成功");
       }
      }
      
打印流 PrintStream 与 PrintWriter
  1. PrintStream 类图

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDBs4amD-1648481509853)(D:/Typora%20Data/Img/image-20220319101151325.png)]

    • 代码

      • public class PrintStream_ {
         public static void main(String[] args) throws IOException {
             String filePath = "d:\\test\\news4.txt";
             PrintStream ps = System.out;
             ps.print("hi,打印流");
        
             System.setOut(new PrintStream(filePath));
             ps = System.out;
             System.out.println("hello01");
             ps.print("hello02");//追加方式
         }
        }
        
  2. PrintWriter 类图

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RAaywfYL-1648481509853)(D:/Typora%20Data/Img/image-20220319101320659.png)]

    • 代码

      • public class PrintWriter_ {
         public static void main(String[] args) throws FileNotFoundException {
             String filePath = "d:\\test\\news4.txt";
        //        PrintWriter printWriter = new PrintWriter(System.out);
             PrintWriter printWriter = new PrintWriter(filePath);
             printWriter.print("北京你好~~");
             printWriter.close();//关闭流相当于flush + 关闭
         }
        }
        
练习作业
  1. /**
     * 在判断e盘下是否有文件夹mytemp ,如果没有就创建myTemp
     * 在e:\myTemp目录下,创建文件hello.txt
     * 如果hello.txt已经存在,提示该文件已经存在,就不要再重复创建了
     * 并且在hello.txt文件中,写入hello,world~
     */
    
    public class HomeWorks01 {
        public static void main(String[] args) throws IOException {
            String directPath = "d:\\test\\myTemp";
            File file = new File(directPath);
            if (!file.exists()) {
                if (file.mkdirs()) {
                    System.out.println(directPath + "文件创建成功");
                }else {
                    System.out.println( directPath + "文件创建失败");
                }
            }
            String filePath = directPath + "\\hello.txt";
            file = new File(filePath);
            BufferedWriter bufferedWriter = null;
            if (!file.exists()) {
                if (file.createNewFile()) {
                    System.out.println(filePath + "文件创建成功");
                    bufferedWriter = new BufferedWriter(new FileWriter(filePath));
                    bufferedWriter.write("hello,world");
                }else {
                    System.out.println("文件创建失败");
                }
            }else {
                System.out.println(filePath + "文件已经存在");
                bufferedWriter = new BufferedWriter(new FileWriter(filePath));
                bufferedWriter.write("hello,world");
            }
            bufferedWriter.close();
        }
    }
    
  2. public class HomeWork02 {
     /**
         * 要求:使用BufferedReader读取一个文本文件,为每行加上行号,
         * 再连同内容一并输出到屏幕上。
         */
        public static void main(String[] args) {
            String filePath = "d:\\test\\news1.txt";
            BufferedReader br = null;
            String readLen;
            int num = 0;
            try {
                br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
                while((readLen = br.readLine()) != null) {
                    System.out.println(num++ + " " + readLen);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  3. public class HomeWork03 {
     /**
         * (1)要编写-个dog.properties
         * name=tom
         * age=5
         * color= red
         * (2)编写Dog类(name,age,color)创建一个dog对象, 读取dog.properties 用相应的内容完成属性初始化,并输出
         * (3)将创建的Dog对象,序列化到文件dog.dat文件
         */
        public static void main(String[] args) {
        }
    
        @Test
        public void m1() throws IOException {
            String filePath = "C:\\Users\\86152\\IdeaProjects\\kuangshen-study\\baseLearn\\src\\com\\su\\properties_\\dog.properties";
            Properties properties = new Properties();
            FileReader fr = new FileReader(filePath);
            properties.load(fr);
            String name = properties.get("name") + "";
            int age = Integer.parseInt(properties.get("age") + "");
            String color = properties.get("color") + "";
            Dog dog = new Dog(name, age, color);
            System.out.println("dog的相关信息" + dog);
            String serFilePath = "d:\\test\\data.dat";
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(serFilePath));
            oos.writeObject(dog);
            System.out.println("dog序列化完成");
            fr.close();
            oos.close();
        }
    
        @Test
        public void m2() throws IOException, ClassNotFoundException {
            String serFilePath = "d:\\test\\data.dat";
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(serFilePath));
            Dog dog = (Dog)ois.readObject();
            System.out.println(dog);
            ois.close();
        }
    }
    class Dog implements Serializable{
        private String name;
        private int age;
        private String color;
    
        public Dog(String name, int age, String color) {
            this.name = name;
            this.age = age;
            this.color = color;
        }
    
        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", color='" + color + '\'' +
                    '}';
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值