File类的特点?如何创建File类对象?Java中如何操作文件内容,什么是Io流Io流如何读取和写入文件?字节缓冲流使用原则?

时间:2024-01-27 20:38:15

 

                          重难点提示

 

 

 

                          学习目标

1、能够了解File类的特点(存在的意义,构造方法,常见方法)

2、能够了解什么是IO流以及分类(IO流的概述以及分类)

3、能够掌握字节输出流的使用(继承体系结构介绍以及常见的字节输出流)

4、能够掌握字节输入流的使用(继承体系结构介绍以及常见的字节输入流)

5、能够掌握字节缓冲流(了解)的使用(拷贝文件,传输原理)

 

                          知识点梳理

 

 

                          超详细讲义

==知识点==

  1. File

  2. IO流

  3. 字节流

1.File类

1.1File和IO的概述【了解】(视频01)(5‘’)

Java中用哪个类表示文件或文件夹?

JavaAPI :java.io.File 类 :创建、删除、重命名等操作

1.2File类构造方法【重点】(视频02) (6‘’)

1.如何创建File对象?

方法名 说明
File(String pathname) 通过指定的路径字符串创建File对象
File(String parent, String child) 通过File表示的文件夹和子路径创建的File对象
File(File parent, String child) 通过File表示的文件夹和子路径创建的File对象

2.File类的特点

只是表示路径名称而已,可以表示存在的,也可以表示不存在的

da示例代码

package com.itheima.filedemo;


import java.io.File;

public class FileDemo1 {

   public static void main(String[] args) {
       //method1();
       //method2();
       //method3();


  }

   private static void method3() {
       //File•(File parent, String child)     从父抽象路径名和子路径名字符串创建新的File实例
       File file1 = new File("C:\\itheima");
       String path = "a.txt";
       File file = new File(file1,path);
       System.out.println(file);//C:\itheima\a.txt
  }

   private static void method2() {
       //File•(String parent, String child)   从父路径名字符串和子路径名字符串创建新的File实例
       String path1 = "C:\\itheima";
       String path2 = "a.txt";
       File file = new File(path1,path2);//把两个路径拼接.
       System.out.println(file);//C:\itheima\a.txt
  }

   private static void method1() {
       //File•(String pathname)       通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
       String path = "C:\\itheima\\a.txt";
       File file = new File(path);
       //问题:为什么要把字符串表示形式的路径变成File对象?
       //就是为了使用File类里面的方法.
  }


}

 

1.3 绝对路径和相对路径【了解】(视频03)(5‘’)

1.绝对路径

是一个完整的路径,从盘符开始

//(对比)

2.相对路径

是一个简化的路径,默认是相对当前项目下的路径

示例代码

package com.itheima.filedemo;

import java.io.File;

public class FileDemo2 {
   public static void main(String[] args) {
       //这个路径固定不变了.
      File file = new File("D:\\itheima\\a.txt");
       System.out.println(file);
      //当前项目下的a.txt
      File file2 = new File("a.txt");
       System.out.println(file2);
      //当前项目下 --- 指定模块下的 a.txt
      File file3 = new File("filemodule\\a.txt");
       System.out.println(file3.getAbsolutePath());
  }
}

1.4File类创建功能【重点】(视频04) (9‘’)

1.方法

方法名 说明 注意事项
public boolean createNewFile() 创建一个新的空文件 如果路径上的文件夹不存的话,就抛异常 :java.io.IOException: 系统找不到指定的路径。
public boolean mkdir() 创建一个单级文件夹 1.只能创建单级文件夹,不能创建多级文件夹 2.如果文件夹已经存在,创建失败
public boolean mkdirs() 创建多级文件夹 1,可以创建单级文件夹,也可以创建多级文件夹 2.文件夹已经存在,创建失败

示例代码

package com.itheima.filedemo;


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

public class FileDemo3 {
   public static void main(String[] args) throws IOException {
       //public boolean createNewFile()   创建一个新的空的文件
               //注意点:
                   //1.如果文件存在,那么创建失败,返回false
                   //2.如果文件不存在,那么创建成功,返回true
                   //3.createNewFile方法不管调用者有没有后缀名,只能创建文件.

       //public boolean mkdir()           创建一个单级文件夹
               //注意点:
                   //1.只能创建单级文件夹,不能创建多级文件夹
                   //2.不管调用者有没有后缀名,只能创建单级文件夹

       //public boolean mkdirs()           创建一个多级文件夹
               //注意点:
                   //1,可以创建单级文件夹,也可以创建多级文件夹
                   //2.不管调用者有没有后缀名,只能创建文件夹

       //疑问:
           //既然mkdirs能创建单级,也能创建多级.那么mkdir还有什么用啊? 是的





       //method1();

       //method2();

       File file = new File("C:\\itheima\\aaa.txt");
       boolean result = file.mkdirs();
       System.out.println(result);


  }
//1.mkdir:创建文件夹
   //2.只要我们起的文件夹名称符合操作系统的要求
   private static void method2() {
       File file = new File("C:\\itheima\\aaa.txt");
       boolean result = file.mkdir();
       System.out.println(result);
  }
//1.createNewFile:创建文件
   //2.文件路径字符串中最后\\之前的路径必须存在
   //3. 文件名只要符合操作系统对文件名的规定就可以创建成功
   //4. 如果文件不存在,ture,如果存在false
   private static void method1() throws IOException {
       File file1 = new File("C:\\itheima\\aaa");
       boolean result1 = file1.createNewFile();
       System.out.println(result1);
  }
}

1.5File类删除功能【重点】(视频05) (4'')

方法分类

方法名 说明 注意事项
public boolean delete() 删除File表示的文件或目录 1.不走回收站的 2.只能删除文件和空文件夹 3.有权限问题的话,无法删除,并且无提示

示例代码

package com.itheima.filedemo;


import java.io.File;

public class FileDemo4 {
   //注意点:
       //1.不走回收站的.
       //2.如果删除的是文件,那么直接删除.如果删除的是文件夹,那么能删除空文件夹
       //3.如果要删除一个有内容的文件夹,只能先进入到这个文件夹,把里面的内容全部删除完毕,才能再次删除这个文件夹
   //简单来说:
       //只能删除文件和空文件夹.
   public static void main(String[] args) {
       //method1();
       File file = new File("C:\\itheima");
       boolean result = file.delete();
       System.out.println(result);
  }

   private static void method1() {
       File file = new File("C:\\itheima\\a.txt");
       boolean result = file.delete();
       System.out.println(result);
  }
}

1.6File类判断和获取功能【重点】(视频06) (6'')

1.判断方法

方法名 说明
public boolean isDirectory() 测试File是否为目录(文件夹)
public boolean isFile() 测试File是否为文件
public boolean exists() 测试File是否存在

2.获取方法

方法名 说明
public String getName() 只返回File表示的文件名称或文件夹的名称

示例代码

package com.itheima.filedemo;


import java.io.File;

public class FileDemo5 {
   //public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
   //public boolean isFile()       测试此抽象路径名表示的File是否为文件
   //public boolean exists()       测试此抽象路径名表示的File是否存在
   //public String getName()       返回由此抽象路径名表示的文件或目录的名称
               //注意点:
                   //1.如果调用者是文件,那么获取的是文件名和后缀名
                   //2.如果调用者是一个文件夹,那么获取的是文件夹的名字
   public static void main(String[] args) {
       //method1();
       //method2();

       //method3();

       File file = new File("a.txt");
       String name = file.getName();
       System.out.println(name);

       File file1 = new File("C:\\itheima");
       String name2 = file1.getName();
       System.out.println(name2);


  }

   private static void method3() {
       File file = new File("a.txt");
       boolean result = file.exists();
       System.out.println(result);
  }

   private static void method2() {
       File file = new File("C:\\itheima");
       boolean result1 = file.isFile();
       boolean result2 = file.isDirectory();
       System.out.println(result1);
       System.out.println(result2);
  }

   private static void method1() {
       File file = new File("C:\\itheima\\a.txt");
       boolean result1 = file.isFile();
       boolean result2 = file.isDirectory();
       System.out.println(result1);
       System.out.println(result2);
  }


}

1.7 File的listFile方法 【重点】(视频07) (7‘’)

方法名 说明 注意事项
File[] listFiles() 获取文件夹下的所有文件和文件夹对象,封装到File数组中返回 1.File指向不存在,返回null 2.存在 2.1存在的是文件:返回null 2.2 存在的是文件夹:正常输出,如果是空文件夹,返回长度为0的Fils数组 3.权限问题,没有访问权限,返回null

示例代码:

package com.itheima.filedemo;


import java.io.File;

public class FileDemo6 {

   public static void main(String[] args) {

      File file = new File("D:\\aaa");
       //1.file可以表存在可以不存在,如果file不存,listFiles,返回null
       //2.如果file表示的是存在的文件时,listFiles,返回null
       //3.如果文件夹有权限的时,listFiles,返回null
       File[] files = file.listFiles();//返回值是一个File类型的数组
       System.out.println(files.length);
       for (File path : files) {
           System.out.println(path);
      }

       //进入文件夹,获取这个文件夹里面所有的文件和文件夹的File对象,并把这些File对象都放在一个数组中返回.
       //包括隐藏文件和隐藏文件夹都可以获取.

       //注意事项:
           //1.当调用者是一个文件时
           //2,当调用者是一个空文件夹时
           //3.当调用者是一个有内容的文件夹时
           //4.当调用者是一个有权限才能进入的文件夹时

  }
}

 

1.8File类练习一【重点】(视频08) (5‘’)

1.案例需求

在当前模块下的aaa文件夹中创建一个a.txt文件

2.实现步骤

  1. 创建File对象,指向aaa文件夹

  2. 判断aaa文件夹是否存在,如果不存在则创建

  3. 创建File对象,指向aaa文件夹下的a.txt文件

  4. 创建这个文件

代码实现

public class Test1 {
   public static void main(String[] args) throws IOException {
       //练习一:在当前模块下的aaa文件夹中创建一个a.txt文件
      /* File file = new File("filemodule\\aaa\\a.txt");
       file.createNewFile();*/
       //注意点:文件所在的文件夹必须要存在.

    //1.创建File对象,指向aaa文件夹
       File file = new File("filemodule\\aaa");
    //2.判断aaa文件夹是否存在,如果不存在则创建
       if(!file.exists()){
           //如果文件夹不存在,就创建出来
           file.mkdirs();
      }
    //3.创建File对象,指向aaa文件夹下的a.txt文件
       File newFile = new File(file,"a.txt");
    //4.创建这个文件
       newFile.createNewFile();
  }
}

1.9File类练习二【重点】(视频09)(7‘’)

1.案例需求

删除一个多级文件夹

2.实现步骤

  • 定义一个方法,接收一个File对象

  • 遍历这个File对象,获取它下边的每个文件和文件夹对象

  • 判断当前遍历到的File对象是文件还是文件夹

  • 如果是文件,直接删除

  • 如果是文件夹,递归调用自己,将当前遍历到的File对象当做参数传递

  • 参数传递过来的文件夹File对象已经处理完成,最后直接删除这个空文件夹

代码实现

package com.itheima.filetest;


import java.io.File;

public class Test2 {
   public static void main(String[] args) {
       //练习二:删除一个多级文件夹
       //delete方法
       //只能删除文件和空文件夹.
       //如果现在要删除一个有内容的文件夹?
       //先删掉这个文件夹里面所有的内容.
       //最后再删除这个文件夹

       File src = new File("C:\\Users\\apple\\Desktop\\src");
       deleteDir(src);

  }

   private static void deleteDir(File src) {
       //先删掉这个文件夹里面所有的内容.
       //递归 方法在方法体中自己调用自己.
       //注意: 可以解决所有文件夹和递归相结合的题目
       //1.进入 --- 得到src文件夹里面所有内容的File对象.
       File[] files = src.listFiles();
       //2.遍历 --- 因为我想得到src文件夹里面每一个文件和文件夹的File对象.
       for (File file : files) {
           if(file.isFile()){
               //3.判断 --- 如果遍历到的File对象是一个文件,那么直接删除
               file.delete();
          }else{
               //4.判断
               //递归
               deleteDir(file);//参数一定要是src文件夹里面的文件夹File对象
          }
      }
       //最后再删除这个文件夹
       src.delete();
  }


}

1.10 File类练习的递归分析(难点) (视频10)(6'')

 

 

 

1.11File类练习三【难点】(视频11) (8'')

(共3点)

1.案例需求

统计一个文件夹中每种文件的个数并打印

打印格式如下:

txt:3个 doc:4个 jpg:6个

2.实现步骤

  • 定义一个方法,参数是HashMap集合用来统计次数和File对象要统计的文件夹

  • 遍历File对象,获取它下边的每一个文件和文件夹对象

  • 判断当前File对象是文件还是文件夹

  • 如果是文件,判断这种类型文件后缀名在HashMap集合中是否出现过

    • 没出现过,将这种类型文件的后缀名存入集合中,次数存1

    • 出现过,获取这种类型文件的后缀名出现的次数,对其+1,在存回集合中

  • 如果是文件夹,递归调用自己,HashMap集合就是参数集合,File对象是当前文件夹对象

代码实现

package com.itheima.filetest;

import java.io.File;
import java.util.HashMap;

public class Test3 {
   public static void main(String[] args) {
       //统计一个文件夹中,每种文件出现的次数.
       //统计 --- 定义一个变量用来统计. ---- 弊端:同时只能统计一种文件
       //利用map集合进行数据统计,键 --- 文件后缀名 值 ---- 次数

       File file = new File("filemodule");
       HashMap<String, Integer> hm = new HashMap<>();
       getCount(hm, file);
       System.out.println(hm);
  }

   /***
    * 获取文件夹下的每种文件出现的次数
    * @param hm 存储每种文件出现的次数
    *           每种文件与出现的个数之间,是一一对应的关系
    *           因此文件类型作为key,出现的个数作为value
    * @param file 被统计的文件夹
    */
   private static void getCount(HashMap<String, Integer> hm, File file) {
       //1.第一步,遍历获取文件夹下所有的文件和文件夹
       File[] files = file.listFiles();
       //2.遍历
       for (File f : files) {
           //3.判断是不是文件
           if(f.isFile()){
               //3.1 如果是文件,获取文件的后缀名
               String fileName = f.getName();
               String[] fileNameArr = fileName.split("\\.");
               if(fileNameArr.length == 2){
                   String fileEndName = fileNameArr[1];
                   //3.2 判断map集合中有没有文件后缀的key
                   if(hm.containsKey(fileEndName)){
                       //3.2.1 如果有表示存在,将已经出现的次数获取出来
                       Integer count = hm.get(fileEndName);
                       //3.2.2 将出现的次数加1
                       count++;
                       //3.2.3 将新的次数赋值给对应的后缀名
                       hm.put(fileEndName,count);
                  }else{
                       //3.3 如果不存在,直接放入map集合中,次数为1
                       hm.put(fileEndName,1);
                  }
              }
          }else{
               //4.不是文件,继续调用方法自己获取文件夹下每种文件出现的次数
               getCount(hm,f);
          }
      }
  }
}

3.代码分析

 

 

 

 

小结

1.什么是File类

2.如何创建File对象?

3.相对路径和绝对路径

4.File对象中常见的方法

2.IO

2.1 IO 的概述【了解】(视频12) (4‘’)

1.什么IO流(输入和输出站在内存方来说的)

I表示intput,是数据从硬盘进内存的过程,称之为读

O表示output,是数据从内存到硬盘的过程,称之为写

流是一种抽象概念,数据在设备间的传输称为流,流的本质是数据传输

 

 

 

 

2.2 IO流分类【重点】(视频13) (5‘’)

1.IO流的体系

 

 

3.字节流

3.1 字节流-字节输出流快速入门【重点】(视频14) (4‘’)

1.字节流的抽象基类

  • InputStream:这个抽象类是表示字节输入流的所有类的超类

  • OutputStream:这个抽象类是表示字节输出流的所有类的超类

  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

2.如何读写文件?

使用FileInputStream和FileOutputStream读写文件

3.使用字节输出流写数据的步骤

 

 

package com.itheima.output;


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

public class OutputDemo1 {
   public static void main(String[] args) throws IOException {
       //1.创建字节输出流的对象 --- 告诉虚拟机我要往哪个文件中写数据了
       FileOutputStream fos = new FileOutputStream("D:\\a.txt");
       //FileOutputStream fos = new FileOutputStream(new File("D:\\a.txt"));

       //2,写数据
       fos.write(97);

       //3,释放资源
       fos.close();


  }
}

 

 

3.2 字节流-注意事项 (了解) (视频15)(5'')

 

 

public class OutputDemo2 {
   public static void main(String[] args) throws IOException {
       //1.创建字节输出流的对象
                       //注意点:如果文件不存在,会帮我们自动创建出来.
                       //       如果文件存在,会把文件清空.
       FileOutputStream fos = new FileOutputStream("C:\\itheima\\a.txt");

       //2,写数据     传递一个整数时,那么实际上写到文件中的,是这个整数在码表中对应的那个字符.
       fos.write(98);

       //3,释放资源
       fos.close(); //告诉操作系统,我现在已经不再用这个文件了.

  }
}

3.3字节流-一次写多个数据【重点】(视频16)(5'')

  • 写数据的方法分类

    方法名 说明
    void write(int b) 将指定的字节写入此文件输出流 一次写一个字节数据
    void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
    void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据
  • 示例代码

    package com.itheima.output;

    import java.io.FileOutputStream;
    import java.io.IOException;

    public class OutputDemo4 {
     public static void main(String[] args) throws IOException {
           FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");

           /*byte [] bys = {97,98,99};
           fos.write(bys);*/

           byte [] bys = {97,98,99,100,101,102,103};
         fos.write(bys,1,2);

           fos.close();
      }
    }

3.4字节流写数据的两个小问题【重点】(视频17) (6‘’)

(共2点)

1.字节流写数据如何实现换行

  • windows:\r\n

  • linux:\n

  • mac:\r

//System.getProperty("line.separator")
package com.itheima.output;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputDemo5 {
   public static void main(String[] args) throws IOException {
       //第二个参数就是续写开关,如果没有传递,默认就是false,
       //表示不打开续写功能,那么创建对象的这行代码会清空文件.

       //如果第二个参数为true,表示打开续写功能
       //那么创建对象的这行代码不会清空文件.
       FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");

       fos.write(97);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(98);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(99);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(100);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(101);
       //能加一个换行
       fos.write("\r\n".getBytes());

       fos.close();
  }
}

2.字节流写数据如何实现追加写入

  • public FileOutputStream(String name,boolean append)

  • 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头

示例代码

package com.itheima.output;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputDemo5 {
   public static void main(String[] args) throws IOException {
       //第二个参数就是续写开关,如果没有传递,默认就是false,
       //表示不打开续写功能,那么创建对象的这行代码会清空文件.

       //如果第二个参数为true,表示打开续写功能
       //那么创建对象的这行代码不会清空文件.
       FileOutputStream fos = new FileOutputStream("bytestream\\a.txt",true);

       fos.write(97);
       //能加一个换行
       //System.getProperty("line.separator")
       fos.write("\r\n".getBytes());
       fos.write(98);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(99);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(100);
       //能加一个换行
       fos.write("\r\n".getBytes());
       fos.write(101);
       //能加一个换行
       fos.write("\r\n".getBytes());

       fos.close();
  }
}

3.5字节流写数据加异常处理【重点】(视频18) (6‘’)

1.如何捕获异常呢?

try-catch-finally

2.异常处理格式

try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}finally{
执行所有清除操作;
}

3.为什么要使用finally

被finally控制的语句一定会执行 不管有没有异常,也不管异常有没有被捕获,除非JVM退出

示例代码

package com.itheima.output;

import java.io.FileOutputStream;
import java.io.IOException;

public class OutputDemo6 {
   public static void main(String[] args) {
       FileOutputStream fos = null;
       try {
           //System.out.println(2/0);
           fos = new FileOutputStream("D:\\a.txt");
           fos.write(97);
      }catch(IOException e){
          e.printStackTrace();
      }finally {
           //finally语句里面的代码,一定会被执行.
           if(fos != null){
               try {
                   fos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }

  }
}

3.6 字节流-写文本数据小结【重点】 (视频19)(1'')

 

 

3.7字节流-字节输入流基本学习(一次读一个字节数据)【重点】(视频20) (5‘’)

1.如何读文件?

import java.io.FileInputStream类

2.构造方法

方法 说明
FileInputStream(File file) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名

3.字节输入流读取文件数据的步骤

  • 创建字节输入流对象

  • 调用字节输入流对象的读数据方法

  • 释放资源

示例代码

package com.itheima.output;


import java.io.FileInputStream;
import java.io.IOException;

public class OutputDemo7 {
    public static void main(String[] args) throws IOException {
        //如果文件存在,那么就不会报错.
        //如果文件不存在,那么就直接报错.
        FileInputStream fis = new FileInputStream("bytestream\\a.txt");

        int read = fis.read();
        //一次读取一个字节,返回值就是本次读到的那个字节数据.
        //也就是字符在码表中对应的那个数字.
        //如果我们想要看到的是字符数据,那么一定要强转成char


        System.out.println((char)read);

        //释放资源
        fis.close();
    }
}

3.8 字节流读取多个字节 (重点) (视频21) (4'')

package com.itheima.output;


import java.io.FileInputStream;
import java.io.IOException;

public class OutputDemo8 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("bytestream\\a.txt");
        //1,文件中多个字节我怎么办?
        /*while(true){
            int i1 = fis.read();
            System.out.println(i1);
        }*/

        int b;
        while ((b = fis.read())!=-1){
            System.out.println((char) b);
        }
        fis.close();
    }
}

3.9字节流复制文件【重点】(视频22) (6‘’)

案例需求

把“E:\itcast\窗里窗外.txt”复制到模块目录下的“窗里窗外.txt” (文件可以是任意文件)

实现步骤

  • 复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)

  • 数据源:

    E:\itcast\窗里窗外.txt --- 读数据 --- InputStream --- FileInputStream

  • 目的地:

    myByteStream\窗里窗外.txt --- 写数据 --- OutputStream --- FileOutputStream

代码实现

package com.itheima.output;

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

public class OutputDemo9 {
    public static void main(String[] args) throws IOException {
        //创建了字节输入流,准备读数据.
        FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi");
        //创建了字节输出流,准备写数据.
        FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");

        int b;
        while((b = fis.read())!=-1){
            fos.write(b);
        }

        fis.close();
        fos.close();
    }
}

3.10字节流-定义小数组拷贝【重点】(视频23)(8‘’)

1.如何提高文件拷贝的速度?

一次性读写多个字节

2.方法

方法 说明
public int read(byte[] b) throws IOException 从输入流读取最多b.length个字节的数据放入数组中
public void write(byte b[], int off, int len) throws IOException 从字节数组下标off开始,将其中len个数据写入到文件的输出流中

示例代码

package com.itheima.output;

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

public class OutputDemo10 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\1.mp4");
        FileOutputStream fos = new FileOutputStream("bytestream\\1.mp4");

        byte [] bytes = new byte[1024];
        int len;//本次读到的有效字节个数 --- 这次读了几个字节
        while((len = fis.read(bytes))!=-1){
            System.out.println(bytes);
            fos.write(bytes,0,len);
        }

        fis.close();
        fos.close();
    }
}

3.11 字节流-小数组拷贝的原理【难点】 (视频24) (5‘’) 填数据

 

 

小结

1.什么是IO流?

2.IO流的分类?

3.字节输入流?

4.字节输出流?

5.如何提高读写效率?

4.字节缓冲流

4.1字节缓冲流-一次读写一个字节代码实现【重点】(视频25) (7‘’)

1.字节缓冲流介绍

  • BufferedOutputStream:字节缓冲输出流

  • BufferedInputStream: 字节缓冲输入流

2.如何使用?(共两点)

2.1 构造方法:

方法名 说明
BufferedOutputStream(OutputStream out) 创建字节缓冲输出流对象
BufferedInputStream(InputStream in) 创建字节缓冲输入流对象

为什么构造方法需要的是字节流,而不是具体的文件或者路径?

 

 

2.2 常用方法

方法 说明
public int read() throws IOException 从输入流中读出8192个字节到缓冲数组中,再从缓冲数组中取出一个字节
public void write(int b) throws IOException 将字节b写入到缓冲数组中,当缓冲数组满时,一次性写入目标文件

示例代码

package com.itheima.output;


import java.io.*;

public class OutputDemo11 {
    public static void main(String[] args) throws IOException {
        //就要利用缓冲流去拷贝文件

        //创建一个字节缓冲输入流
        //在底层创建了一个默认长度为8192的字节数组。
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));
        //创建一个字节缓冲输出流
        //在底层也创建了一个默认长度为8192的字节数组。
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));

        int b;
        while((b = bis.read()) != -1){
            bos.write(b);
        }

        //方法的底层会把字节流给关闭。
        bis.close();
        bos.close();

    }
}

4.2字节缓冲流一次读写一个字节代码原理【难点 】(视频26)(7‘’)

 

 

1.字节缓冲输入流每次读取buffer长度个字节

2.字节缓冲输出流写数据时先将缓冲字节输入流缓冲数组中的数据每次转移1个字节到自己的缓冲数组中,当缓冲数组满时,字节流一次性写出缓冲数组长度个字节

3.如果缓冲数组不满时,当调用缓冲流的close()方法时会将缓冲数组中数据写出

4.3字节缓冲流一次读写一个字节数组【重点 】(视频27)(6‘’)

(共3点)

1.方法

方法 说明
public int read(byte b[]) throws IOException 从输入流中读出8192个字节到缓冲数组中,再从缓冲数组中取出数组b.length个字节到数组b中
public void write(byte b[], int off, int len) throws IOException 将数组b中的元素,从下标0开始,向缓冲数组中写入len个字节,当缓冲数组满时,一次性写入目的地

2.代码实现

package com.itheima.output;

import java.io.*;

public class OutputDemo12 {
    public static void main(String[] args) throws IOException {
        //缓冲流结合数组,进行文件拷贝

        //创建一个字节缓冲输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));

        //创建一个字节缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));

        byte [] bytes = new byte[1024];
        int len;
        while((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }

        bis.close();
        bos.close();
    }
}

3.原理

 

 

 

 

1.字节缓冲输入流每次读取buffer长度个字节

2.字节缓冲输出流写数据时先将缓冲字节输入流缓冲数组中的数据每次转移bytes长度个字节到自己的缓冲数组中,当缓冲数组满时,字节流一次性写出缓冲数组长度个字节

3.如果缓冲数组不满时,当调用缓冲流的close()方法时会将缓冲数组中数据写出

4.4 小结 【重点】(视频28)(2‘’)

如果不自定义数组,使用缓冲流的效率比字节流要高

 

                          扩展练习

 

题目1[File]

请在D盘根目录下创建一个文件:test1.txt(随意录入一些内容),再创建一个目录:测试目录

要求:

  1. 获取、打印file1和file2的绝对路径;

  2. 获取、打印file1和file2的文件名和目录名;

  3. 获取、打印file1和file2的文件大小;

  4. 分别判断file1和file2是否存在;

  5. 分别判断file1和file2是否是文件?是否是目录?

效果:

 

 

 

 

参考代码:

package day11.No_1;

import java.io.File;

public class Demo {
   public static void main(String[] args) {
       File file1=new File("E:\\test1.txt");
       File file2=new File("E:\\测试目录");
       System.out.println("文件1的绝对路径是:"+file1);
       System.out.println("文件夹2的绝对路径是:"+file2);
       String name1 = file1.getName();
       String name2 = file2.getName();
       System.out.println("文件1长度:"+file1.length());
       System.out.println("文件夹2长度:"+file2.length());
       System.out.println("文件1的名称是:"+name1);
       System.out.println("文件夹2的名称是:"+name2);
       System.out.println("file1文件夹存在吗?"+file1.exists());
       System.out.println("file2文件夹存在吗"+file2.exists());
       System.out.println("file1是文件吗"+file1.isFile());
       System.out.println("file2是文件吗"+file2.isFile());
  }
}

运行效果:

 

 

 

题目2[File]

请编写main()方法,创建以下File对象:

File file1 = new File(“test.txt”);//相对路径

File file2 = new File(“一级目录”);

File file3 = new File(“目录A/目录B/目录C”);

要求:

(相对路径,可以相对于项目也可以相对于模块)

  1. 判断file1是否存在?如果不存在,创建这个文件。

  2. 判断file2是否存在?如果不存在,创建这个目录。

    1. 判断file3是否存在?如果不存在,创建这个多级目录。

效果:

 

 

参考代码:

package day11.No_2;

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

public class Demo {
   public static void main(String[] args) throws IOException {
       File file1 = new File("test.txt");//相对路径
       File file2 = new File("mrlx\\ccc");
       File file3=new File("aaa\\aa\\aa");
       if (!file1.exists()){
           System.out.println(file1.createNewFile());
      }
       if (!file2.exists()){
           System.out.println(file2.mkdir());
      }
       if (!file3.exists()){
           System.out.println(file3.mkdirs());
      }
  }
}

 

 

题目3[File]

请在D盘下创建一个目录“多级目录”,下面随意创建一些文件和目录。

请编写main()方法,创建以下File对象:

File file = new File(“D:\多级目录”);

要求:

遍历这个多级文件夹下的所有内容(包含子文件夹的内容),判断每个File对象是否文件

如果是文件,打印:【文件】+ 绝对路径

如果是目录,打印:【目录】+ 绝对路径

效果

 

 

 

 

参考代码:

package day11.No_3;

import java.io.File;

public class Demo3 {
   public static void main(String[] args) {
       File file=new File("E:\\itheima");
       getMulu(file);
  }

   private static void getMulu(File file) {
       File[] files = file.listFiles();
       for (File f : files) {
           if (f.isFile()){
               System.out.println("文件"+f.getAbsolutePath());
          }else{
               System.out.println("文件夹"+f.getAbsolutePath());
               getMulu(f);
          }
      }
  }
}

运行效果:

 

 

 

题目4[File综合题有难度]

请使用代码计算出你电脑上的任意一个文件夹中的大小。

要求:

必须是一个多层文件夹;

效果

 

 

(每个人的具体数据都不一样,以实际情况为准)

参考代码:

package day11.No_4;

import java.io.File;

public class Demo {
   public static void main(String[] args) {
       File file=new File("E:\\临时文件");
       long len=getLeng(file);
       System.out.println(len);
  }

   private static long getLeng(File file) {
       File[] files = file.listFiles();
       long len=0;
       for (File f : files) {
           if (f.isFile()){
               len += f.length();
          }else {
               getLeng(f);
          }
      }
       return len;
  }
}
运行效果:

 

 

 

 

题目5[IO]

使用键盘输入多个学生的信息,并将这些学生的信息保存到模块的1.txt文件中;

要求:

1:学生信息包含姓名、年龄(用一行字符串表示即可,无需创建学生对象);

2:每个学生信息占一行,学生信息之间使用逗号分隔;

3:至少输入3个学生信息;

效果

 

 

 

 

参考代码:

package day11.No_5;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Demo {
   public static void main(String[] args) throws IOException {
       FileOutputStream f=new FileOutputStream("1.txt");
       Scanner sc=new Scanner(System.in);
       int i=1;
       while (true){
           System.out.println("请输入第"+i+"个学生的信息,用逗号分隔");
           String s = sc.next();
           if (s.equals("ok")){
               System.out.println("拜拜!");
               break;
          }
           f.write((s+"\r\n").getBytes());
           i++;
      }
       f.close();
  }
}

 

 

题目6[IO-综合题2有难度-明天做会更简单]

将上一题产生的文件中的学生按照年龄升序排序后重新写回原文件;

效果

1.txt文件排序前:

 

 

1.txt文件排序后:

 

 

参考代码:

public static void main(String[] args) throws Exception {
       File f = new File("1.txt");
       //创建文件对象,准备读数据
       FileInputStream fin = new FileInputStream(f);
       byte[] arr = new byte[(int)f.length()];//文件中有多少字节,就创建多大的数组,一次性读完
       fin.read(arr);//读到的数据都保存到了arr中
       //把数组转成字符串
       String s = new String(arr);
       //使用换行符切分字符串
       String[] split = s.split("\r\n");
       //再使用逗号切分数组中的每一个元素,可以得到学生的姓名和年龄
       //创建set集合并指定排序规则
       TreeSet<Student> set = new TreeSet<>((s1,s2)->s1.getAge()-s2.getAge()==0?s1.getName().compareTo(s2.getName()):s1.getAge()-s2.getAge());
       for (String s1 : split) {
           String[] split1 = s1.split(",");
           //把按照切分出来的数组的第1个值作为name,第二个值作为age创建学生对象,并按照年龄排序
           Student stu = new Student(split1[0],Integer.parseInt(split1[1]));
           set.add(stu);
      }
       //创建输出流,并把set集合中的学生信息重新写入1.txt文件中;(重写Student的toString方法了)
       FileOutputStream fout = new FileOutputStream("1.txt");
       for (Student stu : set) {
           fout.write((stu.toString()+"\r\n").getBytes());
      }
       fin.close();
       fout.close();
       System.out.println("排序已完成");
  }