侧边栏壁纸
  • 累计撰写 135 篇文章
  • 累计创建 1 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

File&IO流

File

  • file是java.io包下的类,file类的对象,用于代表当前操作系统的文件或文件夹

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

基础操作

创建file类的对象

构造器 说明
public File(String pathname) 根据文件路径创建文件对象
public File(String parent, String child) 根据父路径和子路径名字创建文件对象
public File(File parent, String child) 根据父路径对应文件对象和子路径名字创建文件对象

注意:

  • file对象既可以代表文件也可以代表文件夹
  • file封装的对象仅仅是一个路径名(路径名允许存在,也允许不存在)

demo

package com.xbxaq.file_;

import java.io.File;

public class Test {
    public static void main(String[] args) {
        File file = new File("E:\\Code\\test-java\\day1-test\\src\\com\\xbxaq\\file_\\1.txt");
        System.out.println(file.length());

        //或者

        File file1 = new File("src\\com\\xbxaq\\file_\\1.txt");
        System.out.println(file1.length());

    }
}

image-20240329083413356

判断文件类型&获取文件信息功能

方法名称 说明
public boolean exists() 判断当前文件对象,对应的文件路径是否存在,存在返回true
public boolean isFile() 判断当前文件对象指代的是否是文件,是文件返回true,反之。
public boolean isDirectory() 判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之。
public String getName() 获取文件的名称(包含后缀)
public long length() 获取文件的大小,返回字节个数
public long lastModified() 获取文件的最后修改时间。
public String getPath() 获取创建文件对象时,使用的路径
public String getAbsolutePath() 获取绝对路径

demo

package com.xbxaq.file_;

import java.io.File;

public class Test {
    public static void main(String[] args) {
        File file = new File("src\\com\\xbxaq\\file_\\", "demo.txt");
        //判断当前文件对象的路径是否存在
        System.out.println(file.exists());

        //判断当前对象是否是文件
        System.out.println(file.isFile());

        //判断当前对象是否是文件夹
        System.out.println(file.isDirectory());

        //获取文件的名称
        System.out.println(file.getName());

        //获取文件的大小
        System.out.println(file.length());

        //返回文件最后的修改时间
        System.out.println(file.lastModified());

        //获取创建文件对象时,使用的路径(包含文件名)
        System.out.println(file.getPath());

        //获取创建文件对象时的绝对路径
        System.out.println(file.getAbsolutePath());
        

    }
}

image-20240329084402999

创建文件&删除文件

创建文件

方法名称 说明
public boolean createNewFile() 创建一个新的空的文件
public boolean mkdir() 只能创建一级文件夹
public boolean mkdirs() 可以创建多级文件夹

删除文件

方法名称 说明
public boolean delete() 删除文件、空文件夹

注意:delete方法默认只能删除文件和空文件夹,删除后的文件不会进行Windows机器的回收站

demo

package com.xbxaq.file_;

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

public class Test {
    public static void main(String[] args) throws Exception {
        File file = new File("src/com/xbxaq/file_/2.txt");
        // 基于file对象创建一个空的新文件
        System.out.println(file.createNewFile());

        File file1 = new File("src/com/xbxaq/file_/filedir/");
        //创建一级文件夹
        System.out.println(file1.mkdir());

        File file2 = new File("src/com/xbxaq/file_/filetest/11/22/33/44");
        //创建多级文件夹
        System.out.println(file2.mkdirs());

        File file3 = new File("src/com/xbxaq/file_/1.txt");


        //删除空文件夹和文件(空文件与非空文件都可以进行删除)
        System.out.println(file2.delete());
        System.out.println(file1.delete());
        System.out.println(file.delete());
        System.out.println(file3.delete());
    }
}

image-20240329085653853

遍历文件夹

方法名称 说明
public String[] list() 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
public File[] listFiles() 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)

lisyFiles方法的注意事项:

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

demo

package com.xbxaq.file_;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception {
        File file = new File("src\\com\\xbxaq");
        //file.list()返回字符串中
        String[] names = file.list();
        for (String name:names){
            System.out.println(name);
        }

        //listFiles[]返回文件对象数组中
        File[] files = file.listFiles();
        for (File f:files){
            System.out.println(f.getAbsolutePath());
        }

        //将数组转为字符串
        System.out.println(Arrays.toString(files));
    }
}

image-20240329091101553

递归

  • 递归属于一种算法,从形式上来讲是方法调用自身的形式称为方法递归

递归的形式

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

注意事项:递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误

公式

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

文件夹遍历

package com.xbxaq.file_;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception {
        try {
            searchFile(new File("E:\\code\\test-java"),"123.txt");
        } catch (Exception e) {
            System.out.println("错误啦");
            e.printStackTrace();
        }
    }
    public static void searchFile(File dir,String fileName) throws Exception {
        if (dir == null || !dir.exists() || dir.isFile()){
            return;
        }
        File[] files = dir.listFiles();

        if (files != null && files.length > 0){
            for (File f : files){
                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);
                }
            }
        }
    }
}


image-20240329100738809

字符集

  • 编码:将字符串按照指定字符集编码成字节
  • 解码:把字节按照指定字符集解码成字符

ASCII字符集

  • ASCII(American Standard Code for Information Interchange): 美国信息交换标准代码,包括了英文、符号等
  • 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符

image-20240329101349356

GBK编码

  • 汉字编码字符集,包含了2万多个汉字等字符,GBK中一个汉字字符编码成两个字节的形式存储

注意:GBK编码兼容ASCII字符集

Unicode字符集

也成为统一码或者万国码

  • Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集

UTF-32 四个字节表示一个字符

UTF-8

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

注意:程序员在开发时使用UTF-8编码情况较多

注意事项

  • ASCII字符集:只有英文、数字、符号等,占1个字节
  • GBK字符集:汉字占2个字节,英文、数字占1个字节
  • UTF-8字符集:汉字占3个字节,英文、数字占1个字节
  • 字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
  • 英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码

Java代码完成对字符的编码

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

Java代码完成对字符的解码

String提供了如下方法 说明
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes, String charsetName) 通过指定的字符集解码指定的字节数组来构造新的 String

demo

package com.xbxaq.file_;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception {
        // 1、编码
        String data = "小白学安全 xbxaq.com";
        byte[] bytes = data.getBytes(); // 默认是按照平台字符集(UTF-8)进行编码的。
        System.out.println(Arrays.toString(bytes));

        // 按照指定字符集进行编码。
        byte[] bytes1 = data.getBytes("GBK");
        System.out.println(Arrays.toString(bytes1));

        // 2、解码
        String s1 = new String(bytes); // 按照平台默认编码(UTF-8)解码
        System.out.println(s1);

        String s2 = new String(bytes1, "GBK");
        System.out.println(s2);
    }
}

image-20240329110336372

IO流

  • 用于读写数据(可以读写文件,也可以读取网络中的数据)

image-20240329110438009

流的分类

按照流的方向

  • 输入流
  • 输出流

按照流中数据的最小单位分

  • 字节流,适合操作所有类型的文件
  • 字符流,只适合操作纯文本文件

image-20240329111206458

IO流总体有四大流

  • 字节输入流(InputStream)

  • 字节输出流(OutputStream)

  • 字符输入流(Reader)

  • 字符输出流(Writer)

  • 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流

  • 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。

  • 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。

  • 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。

IO流体系

image-20240329111710261

文件字节输入流

FileInputStream,以内存为基准,把磁盘文件中的数据以字节的形式读入到内存中

方法

构造器 说明
public FileInputStream(File file) 创建字节输入流管道与源文件接通
public FileInputStream(String pathname) 创建字节输入流管道与源文件接通

注意:使用FileInputStream每次读取一个字节,读取性能较差,并且读取汉字输出会乱码

方法名称 说明
public int read() 每次读取一个字节返回,如果发现没有数据可读会返回-1.
public int read(byte[] buffer) 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

demo-read()

package com.xbxaq.io_;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Test {
    public static void main(String[] args) throws Exception {
        //创建字节输入的管道
        //FileInputStream fileInputStream = new FileInputStream("src/com/xbxaq/io_/test.txt");
        FileInputStream fileInputStream = new FileInputStream(new File("src/com/xbxaq/io_/test.txt"));

        //读取字节数据,每次只能读取一个
        int b = fileInputStream.read();
        System.out.println((char) b);

    }
}

image-20240329112754458

demo-read(byte[] buffer)

public class Test1 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个字节输入流对象代表字节输入流管道与源文件接通。
        InputStream is = new FileInputStream("src/com/xbxaq/io_/test.txt");

        byte[] buffer = new byte[3];
        int len; // 记住每次读取了多少个字节。  abc 66
        while ((len = is.read(buffer)) != -1){
            // 注意:读取多少,倒出多少。
            String rs = new String(buffer, 0 , len);
            System.out.print(rs);
        }
        // 性能得到了明显的提升!!
        // 这种方案也不能避免读取汉字输出乱码的问题!!

        is.close(); // 关闭流
    }
}

image-20240329114144500

一次读取完全部的字节

方式一:自己定义一个字节数组与被读取的文件大小一致,然后使用该字节数组,一次性读完文件的全部字节

方法名称 说明
public int read(byte[] buffer) 每次用一个字节数组去读取,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回

方法名称 说明
public byte[] readAllBytes() throws IOException 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回

readAllBytes() 该方法JDK9版本以上才支持

注意:如果读取的文过大,创建的字节数组过大,可能引起内存溢出

文件字节输出流

image-20240329123815626

作用:以内存为基准,把内存中的数据以字节的形式写出文件中

方法名

构造器 说明
public FileOutputStream(File file) 创建字节输出流管道与源文件对象接通
public FileOutputStream(String filepath) 创建字节输出流管道与源文件路径接通
public FileOutputStream(File file,boolean append) 创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filepath,boolean append) 创建字节输出流管道与源文件路径接通,可追加数据
方法名称 说明
public void write(int a) 写一个字节出去
public void write(byte[] buffer) 写一个字节数组出去
public void write(byte[] buffer , int pos , int len) 写一个字节数组的一部分出去。
public void close() throws IOException 关闭流。

demo

package com.xbxaq.io_;

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

public class Test {
    public static void main(String[] args) throws Exception {
        FileOutputStream fileOutputStream = new FileOutputStream("src/com/xbxaq/io_/test.txt", true);
        fileOutputStream.write(97);
        fileOutputStream.write("x".getBytes());

        byte[] bytes = "小白学安全 xbxaq.com".getBytes();

        fileOutputStream.write(bytes);

        fileOutputStream.close();
    }
}

image-20240329124343990

释放资源的方式

try-catch-finally

try{
	......
}catch(IOException e){
	e.printStackTrace();
}finall{

}
  • finally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止。

  • 作用:一般用于在程序执行完成后进行资源的释放操作(专业级做法)。

try-with-resource

JDK 7开始提供了更简单的资源释放方案:try-with-resource

try(定义资源1;定义资源2;…){
	可能出现异常的代码;
}catch(异常类名 变量名){
	异常的处理代码;
} 

  • () 中只能放置资源,否则报错

  • 什么是资源呢?资源一般指的是最终实现了AutoCloseable接口。

该资源使用完毕后,会自动调用其close()方法,完成对资源的释放!

image-20240329124925418

文件的copy

package com.xbxaq.io_;

import java.io.*;


public class Test {
    public static void main(String[] args) throws Exception {
        try (
                // 1、创建一个字节输入流管道与源文件接通
                InputStream is = new FileInputStream("src/com/xbxaq/io_/test.txt");
                // 2、创建一个字节输出流管道与目标文件接通。
                OutputStream os = new FileOutputStream("src/com/xbxaq/io_/testcopy.txt");
    
                MyConnection conn = new MyConnection();
        ){

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

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



public class MyConnection implements AutoCloseable{
    @Override
    public void close() throws Exception {
        System.out.println("释放了与某个硬件的链接资源~~~~");
    }
}

image-20240329125509245

0
博主关闭了所有页面的评论