字符集、IO流(一)

一、File类

day09-字符集、IO流(笔记)_java


长久存储的方式

day09-字符集、IO流(笔记)_System_02


File类,它的就用来表示当前系统下的文件(也可以是文件夹)

1.1 File对象的创建

day09-字符集、IO流(笔记)_System_03


需求我们注意的是:路径中"“要写成”\“, 路径中”/"可以直接用

/*
   目标: 辨析 相对路径 绝对路径

 */
public class FileDemo03 {
    public static void main(String[] args) {
        // 前提是我在day09 src 创建 xiaopeng.txt
        //创建一个File对象 指代xiaopeng.txt的文件
        // 第一种方式 找到文件的绝对路径  带盘符(根)的路径
        //  E:\414\secode\day09\src\xiaopeng.txt
        File f1 = new File("E:\\secode\\day09\\src\\xiaopeng.txt");
        System.out.println(f1);
        System.out.println(f1.exists());
        // 相对路径(注意)  经常写的是相对路径 不带盘符
        //  相对 是 相对的当前 idea中project
        //  E:\414\secode\       day09\src\xiaopeng.txt
        //  当前project          相对路径
        File f2 = new File("day09\\src\\xiaopeng.txt");
        System.out.println(f2);
        System.out.println(f2.exists());

    }
}

1.2 File判断和获取方法

创建File对象的时候,会传递一个文件路径过来。但是File对象封装的路径是存在还是不存在,是文件还是文件夹其实是不清楚的。好在File类提供了方法可以帮我们做判断。

day09-字符集、IO流(笔记)_字节数_04

/*
   目标: 辨析 是否真实文件  辨析  File是文件还是文件夹

 */
public class FileDemo02 {
    public static void main(String[] args) {
        //1:创建一个File对象 指代某个具体的文件
        File f1 = new File("E:\\414\\resource\\出师表.txt");
        System.out.println(f1);

        File f2 = new File("E:\\414\\resource\\厨师表.txt");
        System.out.println(f2);

        // 1:有一个判断方法  exists() 是否是真实文件
        System.out.println("f1是真实的文件吗:"+f1.exists());//true
        System.out.println("f2是真实的文件吗:"+f2.exists());//false

        //如果存在 能不能知道该文件的大小--里面的字节数
        //2: 获取文件大小 length()
        System.out.println("f1文件大小:"+f1.length());


        // 3:File类型 除了指代某个具体的文件 还可以指代文件夹
        File d1 = new File("E:\\414\\resource");
        System.out.println(d1);
        // d1 是文件夹  f1 是文件
        System.out.println("f1是不是文件呢:"+f1.isFile());//true
        System.out.println("d1是不是文件呢:"+d1.isFile());//false

        System.out.println("f1是不是文件夹呢:"+f1.isDirectory());//false
        System.out.println("d1是不是文件夹呢:"+d1.isDirectory());//true




    }
}
public class FileDemo04 {

    public static void main(String[] args) {
        // 创建一个File对象 表达 系统中某个文件
        //  E:\414\resource\出师表.txt
        File file = new File("E:\\414\\resource\\出师表.txt");
        //
//        File file = new File("day09\\src\\xiaopeng.txt");
        //  获取方法
        // 1:获取字节数(只针对文件 不针对文件夹)
        System.out.println("文件的字节数:"+file.length());//2258
        // 2: 获取文件的名字
        System.out.println("文件的名字:"+file.getName());// 带后缀名  出师表.txt
        //3: 获取文件的最后修改时间  long 毫秒值
        long time = file.lastModified();
        System.out.println("文件的最后修改时间:"+time);
        //可以格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("文件修改时间:"+sdf.format(time));// 2023-08-09 08:55:53
        //4:getPath() 获取封装路径
        System.out.println("文件的封装路径:"+file.getPath());// E:\414\resource\出师表.txt
        //5:getAbsolutePath() 获取绝对路径
        System.out.println("文件的绝对路径:"+file.getAbsolutePath());
    }
}

1.3 创建和删除方法

File类提供了创建和删除文件的方法

1.mkdir(): 只能创建单级文件夹、
2.mkdirs(): 才能创建多级文件夹
3.delete(): 文件可以直接删除,但是文件夹只能删除空的文件夹,文件夹有内容删除不了。

1.4 遍历文件夹方法

day09-字符集、IO流(笔记)_java_05

1.当主调是文件时,或者路径不存在时,返回null
2.当主调是空文件夹时,返回一个长度为0的数组
3.当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹路径放在File数组中,并把数组返回
4.当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在FIle数组中,包含隐藏文件
5.当主调是一个文件夹,但是没有权限访问时,返回null

2.3 递归文件搜索

D:\\判断下搜索QQ.exe这个文件,然后直接输出。

1.先调用文件夹的listFiles方法,获取文件夹的一级内容,得到一个数组
2.然后再遍历数组,获取数组中的File对象
3.因为File对象可能是文件也可能是文件夹,所以接下来就需要判断
	判断File对象如果是文件,就获取文件名,如果文件名是`QQ.exe`则打印,否则不打印
	判断File对象如果是文件夹,就递归执行1,2,3步骤
所以:把1,2,3步骤写成方法,递归调用即可。
/**
 * 目标:掌握文件搜索的实现。
 */
public class RecursionTest3 {
    public static void main(String[] args) throws Exception {
          searchFile(new File("D:/") , "QQ.exe");
    }

    /**
     * 去目录下搜索某个文件
     * @param dir  目录
     * @param fileName 要搜索的文件名称
     */
    public static void searchFile(File dir, String fileName) throws Exception {
        // 1、把非法的情况都拦截住
        if(dir == null || !dir.exists() || dir.isFile()){
            return; // 代表无法搜索
        }

        // 2、dir不是null,存在,一定是目录对象。
        // 获取当前目录下的全部一级文件对象。
        File[] files = dir.listFiles();

        // 3、判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象。
        if(files != null && files.length > 0){
            // 4、遍历全部一级文件对象。
            for (File f : files) {
                // 5、判断文件是否是文件,还是文件夹
                if(f.isFile()){
                    // 是文件,判断这个文件名是否是我们要找的
                    if(f.getName().contains(fileName)){
                        System.out.println("找到了:" + f.getAbsolutePath());
                        Runtime runtime = Runtime.getRuntime();
                        runtime.exec(f.getAbsolutePath());
                    }
                }else {
                    // 是文件夹,继续重复这个过程(递归)
                    searchFile(f, fileName);
                }
            }
        }
    }
}

三、字符集

day09-字符集、IO流(笔记)_java_06


需要我们注意汉字和字母的编码特点:

  1. 如果是存储字母,采用1个字节来存储,一共8位,其中第1位是0
  2. 如果是存储汉字,采用2个字节来存储,一共16位,其中第1位是1
  3. 当读取文件中的字符时,通过识别读取到的第1位是0还是1来判断是字母还是汉字
  • 如果读取到第1位是0,就认为是一个字母,此时往后读1个字节。
  • 如果读取到第1位是1,就认为是一个汉字,此时往后读2个字节。
ASCII字符集:《美国信息交换标准代码》,包含英文字母、数字、标点符号、控制字符
	特点:1个字符占1个字节

GBK字符集:中国人自己的字符集,兼容ASCII字符集,还包含2万多个汉字
	特点:1个字母占用1个字节;1个汉字占用2个字节

Unicode字符集:包含世界上所有国家的文字,有三种编码方案,最常用的是UTF-8
    UTF-8编码方案:英文字母、数字占1个字节兼容(ASCII编码)、汉字字符占3个字节

四、IO流(字节流)

4.1 IO流概述

day09-字符集、IO流(笔记)_数组_07

4.2 FileInputStream读取一个字节

需要用到的方法如下图所示:有构造方法、成员方法

day09-字符集、IO流(笔记)_数组_08

4.5 FileOutputStream写字节

使用FileOutputStream往文件中写数据的步骤如下:

第一步:创建FileOutputStream文件字节输出流管道,与目标文件接通。
第二步:调用wirte()方法往文件中写数据
第三步:调用close()方法释放资源

4.6 字节流复制文件

1.需要创建一个FileInputStream流与源文件接通,创建FileOutputStream与目标文件接通
2.然后创建一个数组,使用FileInputStream每次读取一个字节数组的数据,存如数组中
3.然后再使用FileOutputStream把字节数组中的有效元素,写入到目标文件中

/**
 * 目标:使用字节流完成对文件的复制操作。
 */
public class CopyTest5 {
    public static void main(String[] args) throws Exception {
        // 需求:复制照片。
        // 1、创建一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream("D:/resource/meinv.png");
        // 2、创建一个字节输出流管道与目标文件接通。
        OutputStream os = new FileOutputStream("C:/data/meinv.png");

        System.out.println(10 / 0);
        // 3、创建一个字节数组,负责转移字节数据。
        byte[] buffer = new byte[1024]; // 1KB.
        // 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
        int len; // 记住每次读取了多少个字节。
        while ((len = is.read(buffer)) != -1){
            os.write(buffer, 0, len);
        }

        os.close();
        is.close();
        System.out.println("复制完成!!");
    }
}