文件基本操作

目录

文件基础知识

相对路径与绝对路径

文件的读写

理解 "流","读","写"

Java的IO 流分为几种?

字节流如何转为字符流?

InputStream输入流

OutPutStream字节输出流

案例1 :扫描指定目录并删除文件

案例2 :普通文件的复制

案例3 :扫描指定目录并查找


冯诺依曼体系结构

文件是存储在硬盘上的.

硬盘与内存的区别:

  • 内存存储空间小,硬盘空间大
  • 内存访问速度快,硬盘速度慢
  • 内存成本高,硬盘便宜
  • 内存掉电数据丢失,硬盘掉电数据还在

文件基础知识

文件是被操作系统管理的,操作系统内核有一个专门管理文件的模块---文件系统,java通过java.io.File 类针对文件系统进行了一系列的封装.有可读,可写,可执行权限 .注意,有 File 对象,并不代表真实存在该文件

相对路径与绝对路径


从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描
述,而这种描述方式就被称为文件的绝对路径(absolute path)-----从根一直到目的地

以盘符开头的路径是"绝对路径"


我们可以从任意结点出发,进行路径的描述,而这种描述方式就被称为相对路径(relative path),相对于当前所在结点的一条路径 ------(从任意节点到目的地)
以.(当前路径) 或者 ..(当前路径的上一个路径) 开头的路径为"相对路径"

目录时间的分隔符可以是/(斜杠) 也可以是 \(反斜杠)

工作目录 :

文件基本操作_第1张图片

文件构造方法

签名

说明

File(File parent, String
child)

根据父目录 + 孩子文件路径,创建一个新的 File 实例

File(String pathname)

根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者
相对路径

File(String parent, String
child)

根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用
路径表示

文件里既可以是绝对路径也可以是相对路径

构造方法--根据文件创建文件实例

签名

说明

File(File parent, String
child)

根据父目录 + 孩子文件路径,创建一个新的 File 实例

File(String pathname)

根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者
相对路径

File(String parent, String
child)

根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用
路径表示

文件常用方法

修饰符及返回
值类型

方法签名

说明

String

getParent()

返回 File 对象的父目录文件路径

String

getName()

返回 FIle 对象的纯文件名称

String

getPath()

返回 File 对象的文件路径

String

getAbsolutePath()

返回 File 对象的绝对路径

String

getCanonicalPath()

返回 File 对象的修饰过的绝对路径

boolean

exists()

判断 File 对象描述的文件是否真实存在

boolean

isDirectory()

判断 File 对象代表的文件是否是一个目录

boolean

isFile()

判断 File 对象代表的文件是否是一个普通文件

boolean

createNewFile()

根据 File 对象,自动创建一个空文件。成功创建后返
回 true

boolean

delete()

根据 File 对象,删除该文件。成功删除后返回 true

void

deleteOnExit()

根据 File 对象,标注文件将被删除,删除动作会到
JVM 运行结束时才会进行

String[]

list()

返回 File 对象代表的目录下的所有文件名

File[]

listFiles()

返回 File 对象代表的目录下的所有文件,以 File 对象
表示

boolean

mkdir()

创建 File 对象代表的目录

boolean

mkdirs()

创建 File 对象代表的目录,如果必要,会创建中间目

boolean

renameTo(File
dest)

进行文件改名,也可以视为我们平时的剪切、粘贴操

boolean

canRead()

判断用户是否对文件有可读权限

boolean

canWrite()

判断用户是否对文件有可写权限

get方法

  • getParent---获取当前路径的上级路径
  • getName---获取当前文件名
  • getPath---获取文件路径
  • getAbsolutePath---获取绝对路径 ---- 会将工作目录加上
  • getCanonicalPath ---获取精简后的绝对路径

判断的方法

  • exists --- 判断文件是否存在
  • isDirectory --- 判断当前文件是否是一个目录
  • isFile --- 判断当前文件是否是一个普通文件

创建删除文件

  • createNewFile --- 创建一个空文件--成功创建返回false
  • delete() --- 删除文件
  • deleteExit() ---- 程序结束后删除文件

列表方法

  • list -- 返回目录下的所有文件名--用String[]表示
  • listFiles -- 返回目录下的所有文件名--用File对象表示

目录方法

  • mkdir -- 创建单层目录
  • mkdirs ---创建多层目录

文件重命名

  • renameTo --- 修改文件名

判断是否有权限

  • canRead --- 判断文件是否有可读权限
  • canWrite --- 判断文件是否有可写权限

文件的读写

  • 打开文件
  • 关闭文件
  • 读文件
  • 写文件

读写文件之前务必要打开文件,使用文件完毕之后,务必要及时关闭

理解 "流","读","写"

我们在进行IO操作即输入和输出,将数据写入内存(输入),将内存数据输出到磁盘上(输出),输入输出数据过程类似水流简称IO流,对于数据处理的方式也有字节流和字符流

字节流用来操作二进制文件,字符流用来操作文本文件

Java的IO 流分为几种?

java中提供了数据流来进行文件读写,分别是字符流和字节流

字节流 : outputStream(字节输出流) inputStream(字节输入流)

字符流 : writer(字符输出流) reader(字符输入流)

字节流如何转为字符流?

字节输入流转化成字符输入流通过inputStreamWriter 类的构造方法传入字节输入流对象inputStream

字节输出流转字符输出流通过outputStreamWriter类构造方法传入字节输出流对象outStream

文件基本操作_第2张图片

InputStream输入流

inputStream是输入流用来从文件中数据读取到内存中.inputStream不能实例化需要使用FileInputStream来读取文件内容.

inputStream的使用方法介绍

FileinputStream直接可以指定文件路径,可以直接读取字节数据,也可以将数据读取到字节数组中.

  • read()方法 : 返回输入流中的下一个数据(0-255之间),如果返回-1证明到达文件结尾,文件读取结束
  • read(byte[] b) : 将文件数据读取到字节数组中,返回实际读取文件数据长度(最多读取字节数组长度),文件读取数据完毕返回-1
  • read(byte[] b,int off ,int len) ,从offset下标开始读取,返回len-off长度,如果返回-1代表读取文件结束
  • close 关闭字节流---使用完字节流一定要关闭

关闭资源时释放什么资源???

答案是除了内存资源还有一个稀缺资源--文件描述符表

我们利用一个pcb控制块来描述一个进程,有一个重要的属性就是文件描述符表,文件描述符表相当于一个顺序表,表中每一个元素包括打开的文件,每个下标是文件描述符,当我们打开文件时,需要占据一个位置,关闭文件就释放一个位置,所以当一个进程关闭,而一直打开文件,没有释放,就会导致,再次打开文件时,导致打开文件失败.

使用try with resource 自动释放资源

try(InputStream inputStream = new FileInputStream("text.txt")){

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

inputStream的使用

  • 使用read方法
//InputStream--- read()
    
public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("text.txt")){
            while(true){
                int b = inputStream.read();
                if(b==-1){
                    break;
                }
                System.out.printf("%c",b);
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
  • 使用read(byte[] b)
public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("text.txt")){
        byte[] bytes = new byte[1024];
        while(true){
            int len  = inputStream.read(bytes);
            if(len==-1){
                break;
            }
            for(int i =0;i

一般使用inputStream来读取二进制文件,如果要读取文本文件可以使用String转化转成utf8,也可以使用reader来读取文本文件,还可以使用Scanner搭配inputStream使用(推荐使用)

String转换方法

public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("text.txt")){
        byte[] bytes = new byte[1024];
        while(true){
            int len  = inputStream.read(bytes);
            if(len==-1){
                break;
            }
            for(int i =0;i

  • 使用reader方法读取文本文件---返回字符数组
public static void main(String[] args) {
    try(Reader reader = new FileReader("text.txt")){
        char[] chars = new char[1024];
        int len = reader.read(chars);
        for(int i =0;i

  • 推荐使用Scanner搭配inputStream方法
public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("text.txt")){
        Scanner scanner = new Scanner(inputStream);
        while(scanner.hasNext()){
            System.out.println(scanner.next());
        }
    }catch(IOException e){
        e.printStackTrace();
    }

OutPutStream字节输出流

OutputStream主要是将数据写入到文件中

FileOutputStream对象可以直接指定文件路径,可以输出字节数据,也可以输出字节数组数据

这里注意我们每次往文件中写入数据都是先将旧的文件数据清空,重新去写

outputStream方法使用介绍

文件基本操作_第3张图片

write() : 将指定字节数据写入到文件中

write(byte[] b) : 将指定字节数组中的数据写入到文件中,返回实际写入的字节数

write(byte[] b,int off,int len) : 从off下标开始写入长度len个数据到文件中

close : 还是可以使用try with resource 自动关闭资源.

flush : 使用输出流千万不能把flush落下,可能会导致写不进去文件中.

由于IO设备读取速度非常慢,OutputStream为了减少读取次数就加入缓冲区,我们在读取时可能会导致一部分数据还没有写入到设备中,还留在缓冲区,所以我们就需要使用flush刷新一下,将数据刷新到设备中.

当然使用try也可以自动刷新

OutputStream方法使用

  • 使用write方法
public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("text.txt")){
            outputStream.write('h');
            outputStream.write('e');
            outputStream.write('l');
            outputStream.write('l');
            outputStream.write('o');
            outputStream.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }

  • 使用write(byte[] b)
public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("text.txt")){
             byte[] bytes = {'h','e','l','l','0','a','v','a'};
             outputStream.write(bytes);
             outputStream.flush();
        }catch(IOException e){
            e.printStackTrace();
        }
    }

  • 使用printWriter搭配outputStream
public static void main(String[] args) {
    try(OutputStream outPutStream = new FileOutputStream("text.txt")){
        PrintWriter writer = new PrintWriter(outPutStream);
        writer.println("hello,java");
        writer.flush();
    }catch(IOException e){
        e.printStackTrace();
    }
}

案例1 :扫描指定目录并删除文件

public class TestDemo1 {

    /**
     * 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要
     * 删除该文件
     * @param args
     */

    public static void main(String[] args) {
        System.out.println("请输入你要扫描的指定目录路径");
        Scanner scan1 = new Scanner(System.in);
        String s1 = scan1.next();
        File rootPath = new File(s1);//创建路径实例
        if(!rootPath.isDirectory()){
            System.out.println("输入的并不是目录");
            return;
        }
        System.out.println("请输入你要删除的文件");
        Scanner scan2 = new Scanner(System.in);
        String toDelete = scan2.next();

        //开始扫描整个目录--找到与toDelete字符包含的文件
        scanDir(rootPath,toDelete);

    }

    public static void scanDir(File rootPath,String toDelete){
        //将文件目录的文件全部放到file数组里面
        File[] files = rootPath.listFiles();
        if(files==null||files.length==0) {
            return ; //如果目录里面无文件,就不要扫描--退出
        }
        //开始扫描整个目录里的文件
        for(File f : files){
            if(f.isDirectory()){
                //如果扫描的这个还是目录,那就继续深度优先便利--继续扫描此目录--直到找到文件为止
                scanDir(f,toDelete);
            }else {
                //证明不是目录--是一个普通的文件---那我们看是否包含toDelete里的字符
                //进而来判断是否要删除
                tryDelete(f,toDelete);
            }
        }
    }

    public static void tryDelete(File f,String toDelete){
        if(f.getName().contains(toDelete)){
            try {
                System.out.println("你是否要删除此路径下的文件Y/N ==>" + f.getCanonicalPath());
                Scanner scanner = new Scanner(System.in);
                String str = scanner.next();
                if(str.toLowerCase().equals("y")){
                    f.delete();
                    System.out.println("删除成功!!!");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

案例2 :普通文件的复制

public class TestDemo2 {

    /**
     * 进行普通文件的复制
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("请输入你要复制的源文件路径");
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.next();
        File srcFile = new File(s1);
        if(!srcFile.isFile()){
            System.out.println("该文件不是普通的文件~~~");
            return;
        }
        if(!srcFile.exists()){
            System.out.println("该文件不存在~~~");
            return;
        }
        System.out.println("请输入复制的目标路径~~~");
        Scanner scan2 = new Scanner(System.in);
        String s2 = scan2.next();
        File destFile = new File(s2);
        if(destFile.exists()){
            System.out.println("该文件已经存在~~~");
            return ;
        }
        //开始进行复制--读取源文件--复制到目标文件路径
        try(InputStream inputStream = new FileInputStream(srcFile)){
            try(OutputStream outputStream = new FileOutputStream(destFile)){
                byte[] bytes = new byte[1024];
                while(true){
                    int len = inputStream.read(bytes);
                    if(len==-1){
                        break;
                    }
                    outputStream.write(bytes);
                }
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

案例3 :扫描指定目录并查找

public class TestDemo3 {

    /**
     * 扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("请输入你要扫描的指定目录");
        Scanner scan1 = new Scanner(System.in);
        String root = scan1.next();
        File file = new File(root);
        if(!file.isDirectory()){
            System.out.println("不是目录名~~~");
            return;
        }
        System.out.println("请输入你要查找的内容");
        Scanner scan2 = new Scanner(System.in);
        String toFind = scan2.next();

        scanDir(file,toFind);
    }
    public static void scanDir(File file ,String toFind){
        File[] files = file.listFiles();
        if(files==null||files.length==0){
           // System.out.println("该目录里面没有文件~~~");
            return;
        }
        for(File f : files){
            if(f.isDirectory()){
                scanDir(f,toFind);
            }else {
                tryFInd(f,toFind);
            }
        }
    }
    public static void tryFInd(File f, String toFind){
        if(f.getName().contains(toFind)){
            try {
                System.out.println("找到与文件名相匹配的文件" + f.getCanonicalPath());
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try(InputStream inputStream = new FileInputStream(f)){
            byte[] bytes =new byte[1024];
            StringBuilder res = new StringBuilder();
                Scanner scan = new Scanner(inputStream);
                while(scan.hasNext()){
                    res.append(scan.next());
                }
                if(res.indexOf(toFind)>=0){
                    System.out.println("找到了与文件内容相同的文件路径 " + f.getCanonicalPath());
                    return;
                }

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

你可能感兴趣的:(JavaEE,java,数据结构,jvm)