java File和IO流处理

代码地址:https://gitee.com/hippoDocker/java-study/tree/fileAndIo

1、File

File是java.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹)。

作用:通过File类可以获取文件信息(大小、文件名、修改时间等)、判断文件类型、创建文件\文件夹、删除文件\文件夹等。

注意:File只能对文件本身进行操作,不能读写文件里面存储的数据。

1.1.、创建File对象

创建File对象

注意:File对象路径可以指定文件也可以是绝对路径(文件夹)或相对路径,当然也可以指向不存在的路径和文件

// 创建File对象,指代某个具体的文件(绝对路径:从盘符开始)
File f1 = new File("D:\\Txl\\Desktop\\text.txt");
File f2 = new File("D:/Txl/Desktop/text.txt");
File f3 = new File("D:" + File.separator + "Txl" + File.separator + "Desktop" + File.separator + "text.txt");
// 创建File对象,指代某个具体的文件(相对路径:不带盘符,默认直接到当前工程下目录开始寻找)
File f4 = new File("study-commons/java-file-iostream/src/main/resources/file/abc.txt");

/**
* 注意:路径中的斜杠有三种方式:
* 顺斜杠(单斜杠):`D:/Txl/Desktop/test.txt`  
* 反斜杠(双斜杠):`D:\\Txl\\Desktop\\test.txt`
* 自动取系统分隔符:File.separator
**/

1.2、判断文件类型、获取文件信息

判断当前文件对象,对应的文件路径是否存在

// 2.判断当前文件对象,对应的文件路径是否存在,并返回true
System.out.println(f.exists());

判断当前文件对象指代的是否是一个文件

// 3.判断当前文件对象指代的是否是一个文件,并返回true
System.out.println(f.isFile());

判断当前文件对象指代的是否是一个目录

// 4.判断当前文件对象指代的是否是一个目录,并返回true
System.out.println(f.isDirectory());

获取文件名称

// 5.获取文件名称(包含后缀)
System.out.println(f.getName());

获取文件大小

注意:如果file为文件夹,取的是文件夹本身的大小,不包含文件夹里面的内容。

// 6.获取文件大小,返回字节个数
System.out.println(f.length());

获取文件最后修改时间

// 7.获取文件最后修改时间,返回毫秒值
System.out.println(f.lastModified());

获取创建文件对象时,指定的文件路径

// 8.获取创建文件对象时,指定的文件路径
System.out.println(f.getPath());

获取文件的绝对路径

// 9.获取文件的绝对路径
System.out.println(f.getAbsolutePath());

1.3、创建文件、删除文件

创建一个新文件(文件内容为空)

// 根据一个不存的文件创建File对象,调用createNewFile()创建文件
File f5 = new File("study-commons/java-file-iostream/src/main/resources/file/a.txt");
System.out.println(f5.createNewFile());

用于创建文件夹

注意:只能创建一级文件夹

/**
 * 通过指定路径新建File对象,然后调用mkdir()方法,创建文件夹
 * `/aaa`一级路径不存在
 */
File f6 = new File("study-commons/java-file-iostream/src/main/resources/file/aaa");
System.out.println(f6.mkdir());

用于创建文件夹

注意:可以创建多级文件夹

/**
 * 通过指定路径新建File对象,然后调用mkdirs()方法,创建文件夹
 * `/bbb/ccc`多级级路径不存在
 */
File f7 = new File("study-commons/java-file-iostream/src/main/resources/file/aaa/bbb/ccc");
System.out.println(f7.mkdirs());

删除文件或者空文件夹

注意:不能删除非空文件夹,里面只有文件夹也不行

/**
 * 通过指定路径新建File对象,然后调用delete()方法,删除文件或者空文件夹
 * `/aaa`路径下有`/bbb/ccc`存在不能删除,只能删除空文件夹`ccc`
 */
File f8 = new File("study-commons/java-file-iostream/src/main/resources/file/aaa");
System.out.println(f8.delete());

1.4、遍历文件夹

获取指定目录下的所有文件和文件夹的名称,返回String数组

注意:这里的所有文件和文件夹指的是一级文件名称,子文件夹里面的文件不能获取到。

// 1.获取指定目录下的所有文件和文件夹的名称,返回String数组
File f9 = new File("study-commons/java-file-iostream/src/main/resources/file");
String[] names = f9.list();
for (String name : names) {
   
   
    System.out.print(name+",");
}

获取指定目录下的所有文件和文件夹的File对象,返回File数组

注意:这里的所有文件和文件夹指的是一级文件File对象,子文件夹里面的文件不能获取到。

使用listFiles方法时的注意事项:
当主调是文件,或者路径不存在时,返回null
当主调是空文件夹时,返回一个长度为0的数组
当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

// 2.获取指定目录下的所有文件和文件夹的File对象,返回File数组
File[] files = f9.listFiles();
for (File file : files) {
   
   
    System.out.print(file+",");
}

2、方法递归

2.1、认识递归形式

什么是方法递归?

1、递归是一种算法,在程序设计语言中广泛应用。
2、从形式上说:方法调用自身的形式称为方法递归( recursion)。

递归形式

直接递归:方法自己调用自己。
间接递归:方法调用其他方法,其他方法又回调方法自己。

2.2、应用、执行流程、算法思想

栈内存

递归算法三要素:

1、递归的公式: 一个方法就是一个函数,例如f(n) = f(n-1) *n;
2、递归的终结点: f(1);
3、递归的方向必须走向终结点。

2.3、文件搜索

需求:从D盘中,输入某个文件名称,找到后输出它的位置。

分析:
1、先找出D盘下所有一级目录;
2、遍历所有一级目录是否有该文件;
3、如果是文件,就判断是否是我们寻找的文件;
4、如果不是文件就重复上面操作,直到找出文件。

/**
 * TODO 递归搜索文件
 * @param dir 搜索的目录
 * @param fileName 搜索的文件名
 */
public static void searchFile(File dir, String fileName) {
    
    
    // 1.获取当前目录下的所有文件和目录
    File[] files = dir.listFiles();
    if(files != null && files.length > 0) {
    
    
        // 2.遍历files数组
        for (File file : files) {
    
    
            // 3.判断file是否是一个目录
            if (file.isDirectory()) {
    
    
                // 4.如果是目录,继续递归搜索
                searchFile(file, fileName);
            } else {
    
    
                // 5.如果是文件,判断文件名是否和搜索的文件名相同
                if (file.getName().equals(fileName)) {
    
    
                    // 6.如果相同,输出文件的绝对路径
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }
}

3、字符集

3.1、常见字符集介绍

标准ASCALL字符集
1、ASCII(American Standard Code for Information Interchange):美国信息交换标准代码,包括了英文、符号等。

2、标准ASCII使用1个字节存储一个字符首尾是0,总共可表示128个字符,对美国佬来说完全够用。

GBK(汉字内码扩展规范,国标)
1、汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
2、注意:GBK兼容了ASCII字符集。
3、GBK规定:汉字的第一个字节的第一位必须是1。

Unicode字符集(统一码,也叫万国码)
1、Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集。

UTF32:4个字节,由于太占用空间,被淘汰升级为UTF-8

UTF-8
1、是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节;
2、英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节

UTF-8编码方式(二进制)
0xxxxxxx (ASCALL码)
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

例子:a我m:01100001 || 110 001000 010001 || 01101101

注意

所有程序开发都应该使用UTF-8编码。
字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码。
英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码。

总结
1、ASCII字符集:只有英文、数字、符号等,占1个字节。
2、GBK字符集:汉字占2个字节,英文、数字占1个字节。
3、UTF-8字符集:汉字占3个字节,英文、数字占1个字节。

3.2、字符集的编码、解码操作

Java代码完成对字符的编码

String提供以下方法 说明
byte[] getBytes() 使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName) 使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

Java代码完成对字符的解码

String提供了如下方法 说明
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes,String charsetName) 通过指定的字符集解码指定的字节数组来构造新的 String
// TODO 字符集编码解码
// 1.编码:字符串-->字节数组
// 2.解码:字节数组-->字符串
// 3.编码和解码的字符集要一致,否则会出现乱码
// 1.编码:字符串-->字节数组
String s = "你好";
byte[] bytes1 = s.getBytes();// 默认使用工程的字符集(UTF-8)进行编码
byte[] bytes2 = s.getBytes("GBK");// 使用指定字符集(GBK)进行编码
System.out.println("UTF-8编码:"+Arrays.toString(bytes1));
System.out.println("GBK编码:"+Arrays.toString(bytes2));
// 2.解码:字节数组-->字符串
String s1 = new String(bytes1);// 默认使用工程的字符集(UTF-8)进行解码
String s2 = new String(bytes2, "GBK"); // 使用指定字符集(GBK)进行解码
System.out.println("UTF-8解码:"+s1);
System.out.println("GBK解码:"+s2);

4、IO流

作用:用于读写数据(可以读写文件,或者网络中的数据…)

4.1、认识IO流

IO流概述
1、I指Input,称为输入流:负责把数据读到内存中去(磁盘->程序)
2、О指Output,称为输出流:负责写数据出去(程序->磁盘)

4.2、应用场景

文件存储、文件读取、游戏本地数据、复制粘贴、对话交流等。

4.3、如何学习IO流

1、先搞清楚I0流的分类、体系。
2、再挨个学习每个IO流的作用、用法。

IO流的分类
按流的方向划分:IO流:1、输入流;2、输出流。
按流中数据的最小单位划分:IO流:1、字节流;2、字符流。

字节流:适合操作所有类型的文件(比如:音频、视频、图片、文本文件的复制转移等)
字符流:只适合操作存文本文件(比如:读写txt、java等文件)

适合操作所有类型的文件(IO流体系-java.io包)
字节流:字节输入流、字节输出流
字符流:字符输入流、字符输出流
(抽象类-实现类)
字节输入流(InputStream-FileInputStream):以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
字节输出流(OutPutStream-FileOutputStream):以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。
字符输入流(Reader-FileReader):以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。
字符输出流(Writer-FileWriter):以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。

5、IO流-字节流

字节流:适合复制文件等,不适合读写文本文件

5.1、文件字节输入流-FilelnputStream

FilelnputStream(文件字节输入流)
作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去。

构造器 说明
public FileInputStream(File file) 创建字节输入流管道与源文件接通
public FileInputStream(String pathName) 创建字节输入流管道与源文件接通
方法名称 说明
public int read() 读取一个字节返回,如果发现没有数据可读返回-1
public int read(byte[] buffer) 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,
发现没有数据可读返回-1
package com.hippo.javaiostream.iostream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
* @ClassName FileInputStreamOpt
* @Description TODO 文件字节输入流操作
* @Author tangxl
* @create 2023-04-06 14:40
**/
public class FileInputStreamOpt {
    
    
  public static void main(String[] args) throws IOException {
    
    
      // TODO 文件输入流操作
      // 1.文件字节输入流:每次读取一个字节
      // 2.文件字节输入流:每次读取多个字节
      // 3.文件字节输入流:一次性读取所有字节

      // 1.文件字节输入流:每次读取一个字节
      // 1.1 创建文件字节输入流对象
      InputStream in1 = new FileInputStream("study-commons/java-file-iostream/src/main/resources/file/a.txt");
      // 1.1 每次读取一个字节
      int b11 = in1.read();
      System.out.println("b1="+(char)b11);
      int b12 = in1.read
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hippoDocker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值