Java基础知识点 IO流(一)

  • Post author:
  • Post category:java


File,是用来操作系统的文件的。

IO流是用来读写数据的

File创建对象,File对象既可以代表文件,也可以代表文件夹

 public static void main(String[] args) {
            //第一种分隔符
            File file = new File("D:\\a.txt");
            long length = file.length();
            //第二种分隔符
            File file1 = new File("D:/a.txt");
            //第三种分隔符  用File.separator 代替所有的分隔符
            File file2 = new File("D" + File.separator + "a.txt");
            //File也可以指向一个不存在的文件
            File file3 = new File("D:\\aaa.txt");
            boolean exists = file3.exists();   //判断是否存在

            //如何定位模块中的文件    这是他的绝对路径
            File file4 = new File("D:\\Java\\java-01\\java01\\src\\main\\java\\lian02\\b.txt");
            System.out.println(file4.length());
            //最终要的是相对路径
            File file5 = new File("java01\\src\\main\\java\\lian02\\b.txt");
            System.out.println(file5.length());


      }

如何找到文件的绝对路径,右击b.txt文件,选中Copy Paht/Refernece ,选中绝对路径即可。

最重要的是相对路径,如何写相对路径

绝对路径,去掉模块前面的路径就是相对路径。



File提供的判断文件类型、获取文件信息功能

 public static void main(String[] args) {
            //判断当前文件对应的文件路径是否存在
            File file = new File("D:\\a.txt");
            boolean exists = file.exists();
            //判断当前文件是否指向文件
            File file1 = new File("D:\\a.txt");
            boolean file2 = file1.isFile();
            //判断当前文件是否是文件夹
            boolean directory = file1.isDirectory();
            //获取文件名称
            String name = file.getName();
            //获取文件大小
            long length = file.length();
            //获取文件最后修改时间
            long time = file.lastModified();  //获取的是毫米值
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(time);
            System.out.println(format);
            //获取文件创建时获取的路径
            File file3 = new File("D:\\a.txt");
            File file4 = new File("java01\\src\\main\\java\\lian02\\b.txt");
            String path = file3.getPath();
            String path1 = file4.getPath();
            //获取绝对路径
            String absolutePath = file3.getAbsolutePath();
            
      }


掌握File文件创建和删除文件相关方法

public static void main(String[] args) throws IOException {
            //public boolean creatNewFile() 创建新的文件,内容为空
            File file = new File("D:\\b.txt");
            boolean newFile = file.createNewFile();
            //public boolean mkdir()  只能创建一级文件夹
            File file1 = new File("D:\\a");
            boolean mkdir = file1.mkdir();
            //public boolean mkdirs() 创建多级文件夹
            File file2 = new File("D:\\b\\c");
            boolean mkdirs = file2.mkdirs();
            //删除文件或空文件夹,不能删除非空文件夹
            //public boolean delete()
            boolean delete = file1.delete();
            boolean delete1 = file.delete();

      }


File类提供遍历文件夹

public static void main(String[] args) throws IOException {
           //public String[] list()
           // 获取当前目录下所有的一级文件名称到一个字符串数组中返回
            File file = new File("D:\\");   //获取D盘下所有的文件和文件夹名称
            String[] names = file.list();
            for (String name : names) {
                  System.out.println(name);
            }
            //public File[] listFiles[]
            //获取当前目录下所有的一级文件对象到一个文件对象数组中去(重点)
            File[] files = file.listFiles();
            for (File file1 : files) {
                  String absolutePath = file1.getAbsolutePath();
            }
      }

方法递归,计算n的阶乘

递归算法三要素:

递归的公式:f(n) = f(n-1)*n;    递归的终结点:f(1);    递归的方向必须走向终结点。

 public static void main(String[] args) throws IOException {
            System.out.println(f(5));
      }
      public static int f(int n){
            //终结点
            if (n == 1){
                  return 1;
            }else{
                 return f(n - 1)*n;
            }
      }

猴子吃桃问题,每天吃原来桃子的一半,再多吃一个。

public static void main(String[] args) throws IOException {
          //猴子吃桃问题,每天吃原来的一半,再多吃一个。第10天剩下一个
            //  f(x)-f(x)/2-1=f(x+1)
            //f(x)=2f(x+1)+2
            System.out.println(f(1));
      }
      public static int f(int n){
            //终结点
            if (n == 10){
                  return 1;
            }else{
                  return 2*f(n + 1)+2;
            }
      }


文件搜索  (重要)

 public static void main(String[] args) {
            searchFile(new File("D:\\"),"a.txt");
      }
      //搜索文件
      public static void searchFile(File file,String fileName){
            //先判断输入的file是不是合法的
            //file是不是空,是不是目录,路径正不正确
            if (file == null || file.isFile() || !file.exists()){
                  return;
            }
            File[] files = file.listFiles();
            if (files !=null && files.length >0){
                  for (File file1 : files) {
                        if (file1.isFile()){
                              if (file1.getName().equals(fileName)){
                                    System.out.println(file.getAbsolutePath());
                              }
                        }else {
                              searchFile(file1,fileName);
                        }
                  }
            }
      }


删除所有文件(重要)

  public static void main(String[] args) {
            deleteFile(new File("D:\\新建文件夹"));
      }
      //删除文件夹或文件
      public static void deleteFile(File file){
            //如果获取不到访问权限,或者文件地址不存在
           if (file == null || !file.exists()){
                 return;
           }
           //如果是文件直接删除
            if (file.isFile()){
                  file.delete();
                  return;
            }
            //如果是文件夹(先拿到一级文件夹一级对象,判断是否为空)
            File[] files = file.listFiles();
            //如果没有访问权限,直接返回
            if (files == null){
                  return;
            }
            //如果是空文件夹直接删除
            if (files.length == 0){
                  file.delete();
            }
            //如果文件有内容,遍历一级对象
            for (File file1 : files) {
                  if (file1.isFile()){
                        file1.delete();
                  }else{
                        deleteFile(file1);
                  }
            }
            file.delete();// 删除本身,所以判断文件夹为空的代码,可以删除,最后要删除本身

      }


啤酒问题:啤酒2元一瓶,2个瓶子换一瓶,4个盖子换一瓶。10元可以喝几瓶

 public static int allNumber;
    public static int lastBattleNumber;
    public static int lastCoverNumber;

    public static void main(String[] args) {
        buy(10);
        System.out.println(allNumber);
        System.out.println(lastBattleNumber);
        System.out.println(lastCoverNumber);
    }
    public static void buy(int money){
        //先买再说
        int buyNumber = money / 2;
        allNumber += buyNumber;
        //计算本轮总的瓶子数和瓶盖数
        int allBattleNumber = buyNumber + lastBattleNumber;
        int allCoverNumber = buyNumber + lastCoverNumber;
        //计算瓶子数和瓶盖数换算成钱
        //如果说瓶子数大于等于2可以继续换钱
        int allMoney=0;
       if (allBattleNumber >= 2){
           allMoney = (allBattleNumber / 2 )*2;
       }
       lastBattleNumber = allBattleNumber % 2;
       if (allCoverNumber >=4){
           allMoney += (allCoverNumber / 4)*2;
       }
       lastCoverNumber = allCoverNumber % 4;
        //判断allMoney是否大于2,大于2继续买
        if (allMoney >=2){
            buy(allMoney);
        }


    }


字符集

编码:把字符按着指定字符集编码成字节。

解码:把字节按着指定字符集解码成字符。

编码字符串提供的方法

解码通过构造器

        //编码
        String data = "a我b";
        byte[] bytes = data.getBytes();  //按着系统默认编码
        System.out.println(Arrays.toString(bytes));
        //自定义方式编码
        byte[] bytes1 = data.getBytes("GBK");
        System.out.println(Arrays.toString(bytes1));
        //---------------------------------------------------
        //解码 通过new String() 方式
        String s = new String(bytes);
        System.out.println(s);
        String gbk = new String(bytes1, "GBK");
        System.out.println(gbk);


IO流概述


//1.创建文件字节输入流管道,与源文件接通
       InputStream fileInputStream = new FileInputStream(new File("java01\\src\\main\\java\\lian02\\b.txt"));
        //第二种写法,直接写路径更加简化
        InputStream fileInputStream1 = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");

        //2.开始读取字节数据,读取一个字节,如果没有字节了,返回-1
        //public int read();
        int read1 = fileInputStream.read();
        System.out.println(read1);

public static void main(String[] args) throws IOException {
       //1.创建文件字节输入流管道,与源文件接通
       InputStream fileInputStream = new FileInputStream(new File("java01\\src\\main\\java\\lian02\\b.txt"));
        //第二种写法,直接写路径更加简化
        InputStream fileInputStream1 = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");

        //2.开始读取字节数据,读取一个字节,如果没有字节了,返回-1
        //public int read();
        int read1 = fileInputStream.read();
        System.out.println(read1);

        //使用循环改造代码
        int b;  //用于记住读取的字节
        while((b = fileInputStream.read()) !=-1){
            System.out.println(b);
        }
        //一个一个读取性能差
        //读取汉字肯定会乱码,无法避免
        //流使用完毕,必须关闭,释放系统资源
        fileInputStream.close();
        fileInputStream1.close();

    }

一次读取一数组字节

public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
        //b.txt一共就5个数据   afa34
        //开始读取文件的字节数据
        byte[] buffer=new byte[3];
        int read = is.read(buffer);
        String s = new String(buffer);
        System.out.println(s);   //读取为  afa
        //再读取一次
//        int read1 = is.read(buffer);
//        String s1 = new String(buffer);
//        System.out.println(s1);   //读取为   34a
        //读取多少倒多少
        int read2 = is.read(buffer);
        String s2 = new String(buffer, 0, read2);
        System.out.println(s2);
        //如果没有数据,读取结果为-1
        int read3 = is.read(buffer);
        String s3 = new String(buffer);
        System.out.println(s3);   //为-1


    }

简化上述代码

public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
        byte[] bytes=new byte[3];
        int len;  //记住每次读取了多少个字节
        while ((len =is.read(bytes)) != -1){
            String s = new String(bytes,0,len);  //读取多少,倒出多少
            System.out.println(s);
        }
        is.close();//关闭流
        //每次读取多个字节,性能提升
        //还是不能解决中文乱码问题
    }

文件字节输入流,一次读取全部文件

 //一次性读取文件全部字节到一个字节数组中去
        //创建一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
        //准备一个字节数组,大小正好和文件大小一样
        File file = new File("java01\\src\\main\\java\\lian02\\b.txt");
        long length = file.length();
        byte[] bytes=new byte[(int) length];
        int read = is.read(bytes);
        String s = new String(bytes);
        System.out.println(s);

再简化readAllBytes方法

 public static void main(String[] args) throws IOException {
        //一次性读取文件全部字节到一个字节数组中去
        //创建一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
        byte[] bytes = is.readAllBytes();
        System.out.println(new String(bytes));  //再去解码
    }



文件字节输出流

        //创建一个字节输出流管道,与目标文件接通
        //第二个参数,如果是true,表示追加写数据
        //第二个参数如果默认不写,表示覆盖原来数据
        OutputStream os = new FileOutputStream("java01\\src\\main\\java\\lian02\\a.txt",true);
        //开始写字节数据   一次只能写一个字节,写中文会乱码
        os.write(97);
        os.write('b');
        //一次写一个数组
        byte[] bytes = "我爱你中国www".getBytes();
        os.write(bytes);
        //一次写一个数组的指定字节
        os.write(bytes,0,15);
        //   \r\n是换行符,   \n只能兼容windows平台,  \r\n兼容所有平台
        os.write("\r\n".getBytes());
        os.close();


案例-文件复制(这个代码非常重要可以做一切文件的复制,包括文本、图片、视频)

public static void main(String[] args) throws IOException {
        //复制文件
        InputStream is = new FileInputStream("D:\\迅雷\\无标题.png");
        OutputStream os = new FileOutputStream("D:\\无标题.png");
        //创建一个字节数组,负责转移数据
        byte[] bytes = new byte[1024];
        int len;  //记住每次读取了多少个字节
        while ((len = is.read(bytes)) !=-1){
            os.write(bytes,0,len);  //从输入流读取多少个字节,就输出多少个字节
        }
        os.close();
        is.close();
    }

字节流适合做一切文件的复制操作。


流释放存在问题,一旦中间的代码出现问题,流就不能释放。

除了代码中有System.exit(0)  ,否则finally中的代码一定会执行

 try{
           System.out.println(10 / 0);
           return;
           //System.exit(0);退出虚拟机,除了这个代码,finally中的代码一定会执行
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           System.out.println("finally一定执行");
        }

finally中,不要return语句,否则会影响。

public static void main(String[] args) throws IOException {
        System.out.println(chu(2, 1));
    }
    public static int chu(int a,int b){
        try {
            return a / b;
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }finally {
            return 0;
        }
    }

finally一般用于在程序执行完之后进行资源的释放操作。

把复制文件代码用try-catch-finally 代码包围后会报错

因为is和os的定义只在try代码中有效。把InputStream 和OutputStream定义提到try代码外

但是os.close()和is.close() 又会爆红 ,因为finally中的代码一定会执行,如果代码在 InputStream和OutputStream代码定义之前就报错了,就会导致空指针异常。

先对os和is判断对象是否为null,然后再try-catch就可以解决。完整代码如下

public static void main(String[] args) {
        InputStream is=null;
        OutputStream os=null;
        try {
            is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
            os = new FileOutputStream("java01\\src\\main\\java\\lian02\\m.txt");
            //创建一个字节数组负责转移数据
            byte[] bytes=new byte[1024];
            int len;//记住每次读取了多少个字节
            while ((len =is.read(bytes)) != -1){
                os.write(bytes);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os !=null )os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is !=null )is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


上述代码虽然规范,但是太臃肿

//try()的括号里,只能放置资源对象(流对象)
//什么是资源呢?资源都会实现AutoCloseable接口。资源都有一个close()方法
//资源被用完之后,都会自动调用close方法完成资源的释放
 public static void main(String[] args) {
        try ( InputStream is = new FileInputStream("D:\\dog.png");
              OutputStream os = new FileOutputStream("D:\\dogg.png");
              //try()的括号里,只能放置资源对象(流对象)
              //什么是资源呢?资源都会实现AutoCloseable接口。资源都有一个close()方法
              //资源被用完之后,都会自动调用close方法完成资源的释放
              ){
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



版权声明:本文为csdnnbyyds原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。