【JavaEE】文件

目录

文件概念

文件路径

绝对路径

相对路径

文件类型

文本文件

二进制文件

Java中对文件的操作

对文件系统的操作

get相关方法

文件类型判断和创建

文件删除

文件目录的创建

文件重命名

对文件内容的操作

字符流(操作字符数据)

代码例子

删除文件

复制文件


文件概念

本文的文件只是狭义上的文件,就是文件夹和里面的文件。

多说情况下,文件更多的意思是一种软硬件资源的意思,比如网卡。


文件路径

文件路径要注意的是目录级别之间的分割符在Windows系统下既可以是  /  也可以是  \

建议使用  /  因为 \搭配其他字符有可能是转义字符的意思。

文件路径描述了文件的具体位置。 

绝对路径

绝对路径是针对于整个文件系统来说的,描述的路径是从头到尾一个不落。

从D这个盘符开始,把保存这个haha.txt文件的文件夹全部指出来。

相对路径

以当前路径文基准,或者用  .  或者 .. 开头,找到的路径就是相对路径。

当前的路径就是工作路径。假设ATest就是一个工作路径 d:/ATest

想要找到工作路径下面的hello文件夹,就直接可以用  ./hello   表示  (./  表示当前路径)

想要找到工作路径的上面的文件夹,../ATest  可以表示    (../  表示当前路径的上一级)


文件类型

文件类型可以分成两类,一种是二进制文件,一种是文本文件。

文本文件

存的是二进制数据,记事本打开看不懂。

二进制文件

存的是字符串,用记事本打开可以看懂。


Java中对文件的操作

Java对于文件的操作可以分为两大类,对文件系统的操作和文件内容的操作。其中Java标准库提供了File这个类,用来操作文件。

对文件系统的操作

静态成员

 构造方法

构造方法仅仅只是表示文件的路径,至于有没有这个文件它是不管的,也不会创建出一个文件

常用的实例方法

方法说明
String getParent()
判断用户是否对文件有可写权限
String getName()
判断用户是否对文件有可写权限
String getPath()
判断用户是否对文件有可写权限
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相关方法

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

public class IODemo1 {

    public static void main(String[] args) throws IOException {
        File file = new File("D:/ATest/hello/haha.txt");
        System.out.println("该文件的上级路径" + file.getParent());
        System.out.println("该文件的名字" +file.getName());
        System.out.println("该文件的路径" +file.getPath());
        System.out.println("该文件的绝对路径" +file.getAbsolutePath());
        System.out.println("该文件修饰过的绝对路径" +file.getCanonicalPath());
    }

}

文件类型判断和创建

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

public class IODemo2 {

    public static void main(String[] args) throws IOException {

        // 这个文件是存在的
        File file = new File("D:/ATest/hello/haha.txt");
        System.out.println("文件是否存在:" + file.exists());
        System.out.println("是文件夹吗:" + file.isDirectory());
        System.out.println("是文件吗:" + file.isFile());
        System.out.println("能创建出来吗:" + file.createNewFile());
    }

}

文件删除

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

public class IODemo3 {

    public static void main(String[] args) throws IOException {

        // 该文件不存在
        File file = new File("D:/ATest/hello/xixi.txt");
        System.out.println("删除了吗:" + file.delete());
        System.out.println("创建出来了吗:" + file.createNewFile());
        System.out.println("删除了吗:" + file.delete());
        System.out.println("创建出来了吗:" + file.createNewFile());
        file.deleteOnExit();
    }

}

文件目录的创建

import java.io.File;

public class IODemo4 {

    public static void main(String[] args) {

        // 该目录不存在
        // 创建单个文件夹(绝对路径下)
        File file = new File("D:/ATest/lala");
        System.out.println("文件夹存在吗:" + file.exists());
        System.out.println("创建成功了吗:" + file.mkdir());
        System.out.println("文件夹存在吗:" + file.exists());

        // 该目录不存在
        // 创建多个文件夹(在相对路径下)
        File file2 = new File("./Test/lulu");
        System.out.println("文件夹存在吗:" + file2.exists());
        System.out.println("创建成功了吗:" + file2.mkdirs());
        System.out.println("文件夹存在吗:" + file2.exists());
    }

}

文件重命名

// 文件重命名 文件和文件夹都可以
// 这里只测试文件夹

import java.io.File;

public class IODemo5 {

    public static void main(String[] args) {

        // 把刚才Test/lulu文件名改成 heihei
        File file = new File("./Test/lulu");
        File dest = new File("./Test/heihei");
        System.out.println("被修改文件是否存在:" + file.exists());
        System.out.println("不会重名吧::" + dest.exists());
        System.out.println("修改成功了吗:" + file.renameTo(dest));

    }

}

   


对文件内容的操作

对文件内容的操作有两大类,它们都是一种类似于水流的操作。文件内容就像水龙头里的水流,文件里的就是数据流。这两大类分别是字节流和字符流,操作也都是非常相像的。都是打开,关闭,读文件和写文件。此外,对于读和写通常会搞不清楚,通过这个图就能够更好的理解了。


字节流(操作二进制数据) 

通过InputStream、FileInputStream来操作。

字节流读的过程:

打开

使用构造方法打开。 

读+关闭

此时文件内容为

import java.io.*;

// 读文件
// 测试字节流
// InputStream
public class IODemo6 {

    public static void main(String[] args) throws IOException {
        // 创建FileInputStream时,使用相对路径和绝对路径都可以,也可以直接放File对象
        // InputStream 只是一个抽象类,要使用还需要具体的实现类。
        // 关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream类
        // 我们现在只关心从文件中读取,所以使用FileInputStream
        InputStream inputStream = new FileInputStream("D:/ATest/hello/haha.txt");
        InputStream inputStream2 = new FileInputStream("D:/ATest/hello/haha.txt");
        InputStream inputStream3 = new FileInputStream("D:/ATest/hello/haha.txt");


        while(true) {
            // 无参数版本的read()
            // 这里的read()每次只会读一个字节
            int b = inputStream.read();
            if (b == -1) {
                // 当读到文件末尾的时候返回-1
                // 这也就是为什么返回值时int类型
                // 如果是byte的话,无法有多的部分表示 -1
                break;
            }
            System.out.printf("%x ", (byte)b);
        }
        System.out.println();
        System.out.println();

        while (true) {
            // 带有一个参数的read()
            // 这个数组目的是为了返回数据
            byte[] arr1 = new byte[20];
            // 这里的read()读取的数据会尽可能的填满整个数组

            // 如果文件内容不足以填满整个数组,此时返回的是实际长度
            // 然后继续接着读(已到末尾),返回-1  (就是代码这里的情况 4<20)

            // 如果读取完文件还有剩余(意味着数组被填满了, 就先返回实际长度)
            // 然后继续读,并且会覆盖之前数组的值
            // 直到文件读完了,就返回 -1

            int len = inputStream2.read(arr1);
            System.out.println("len : " + len);
            if (len == -1) {
                break;
            }
            // 读出来的放到arr1数组中
            for (int i = 0; i < len; i++) {
                System.out.printf("%x ", arr1[i]);
            }
            System.out.println();
        }
        System.out.println();

        while (true) {
            // 带有三个参数的read()
            byte[] arr2 = new byte[20];
            int off = 0;
            // 存到数组下标为off的位置,每次存 4 个
            int len = inputStream3.read(arr2, 0, 4);
            System.out.println("len : " + len);
            if (len ==  -1) {
                break;
            }
            for (int i = off; i < len; i++) {
                System.out.printf("%x ", arr2[i]);
            }
            System.out.println();
        }

        // 最后要关闭资源。否则会一直保存在pcb的文件资源描述符里
        // 另外close方法还可以把缓冲区里的数据冲刷到内存中,与flush方法效果一样
        inputStream.close();
        inputStream2.close();
        inputStream3.close();
    }
}


字节流写的过程

打开

使用构造方法打开

写+关闭

 此时文件的内容为

// 写文件
// 测试字节流
// OutPutStream

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class IODemo7 {

    public static void main(String[] args) throws IOException {

        // 打开方法于InPutStream一样     // OutputStream打开一个文件,默认会清空原先文件内容
        OutputStream outputStream = new FileOutputStream("D:/ATest/hello/haha.txt");

        // 从头写 ->  a
        outputStream.write(97);
        // a  -> abcd
        byte[] arr1 = {98, 99, 100};
        outputStream.write(arr1);
        // abcd -> abcdgh
        //              e    f    g    h    i
        byte[] arr2 = {101, 102, 103, 104, 105};
        // 从数组下标的2位置开始,写2个数据进去
        outputStream.write(arr2, 2, 2);
        
        // 最后记得关闭
        outputStream.close();

    }


}

若是不想清空原文件的内容,在构造方法上改一下即可。

// 写文件
// 测试字节流
// OutPutStream

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class IODemo8 {

    public static void main(String[] args) throws IOException {

        // true 表示在该文件内容后面追加写                      原内容:abcdgh
        OutputStream outputStream = new FileOutputStream("D:/ATest/hello/haha.txt", true);
        outputStream.write(97);
        outputStream.write(98);
        outputStream.write(99);

        outputStream.close();
    }

}


字符流(操作字符数据)

通过Reader和Writer来操作。(操作和InPutStream、OutPutStream基本完全一致);

// 读文件
// 测试字符流
// Reader

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class IODemo9 {

    public static void main(String[] args) throws IOException {

        // 和InPutStream一样                        内容:abcdghabc
        // 因为 关闭资源在某些情况下有可能执行不到,所以可以放到try里面,多个对象之间用 ; 隔开
        // try最后会自动关闭资源  比finally更方便一些
        // 之前写的代码也可以优化成这种写法
        try (Reader reader = new FileReader("D:/ATest/hello/haha.txt");
             Reader reader2 = new FileReader("D:/ATest/hello/haha.txt");
             Reader reader3 = new FileReader("D:/ATest/hello/haha.txt")){

            while (true) {
                int len = reader.read();
                if (len == -1) {
                    break;
                }
                System.out.printf("%c " ,(char)len);
            }
            System.out.println();
            System.out.println();

            while (true) {
                char[] arr1 = new char[20];
                int len = reader2.read(arr1);
                if (len == -1) {
                    break;
                }
                for (int i = 0; i < len; i++) {
                    System.out.printf("%c ", arr1[i]);
                }
                System.out.println();
            }
            System.out.println();

            while (true) {
                char[] arr2 = new char[20];
                int off = 3;
                int len = reader3.read(arr2, off, 9);
                System.out.println(len);
                if (len == -1) {
                    break;
                }
                for (int i = off; i < len; i++) {
                    System.out.printf("%c ", arr2[i]);
                }
            }
        }

    }

}

这里的写比字节流多了一些方法,可以追加写

// 写文件
// 测试字符流
// Writer

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class IODemo10 {

    public static void main (String[] args) throws IOException {

        // writer 会清空文件原内容写
        // writer2 会保留文件内容写
        try (Writer writer = new FileWriter("D:/ATest/hello/haha.txt");
             Writer writer2 = new FileWriter("D:/ATest/hello/haha.txt", true)){
            writer.write("writer写的");
            writer.append(" 用writer追加写的");
            writer2.write(" writer2写的");
            writer2.append(" 用writer2追加写的");
            // 写完要冲刷进去,防止留在缓冲区
            writer.flush();
            writer2.flush();
        }

    }

}


代码例子

删除文件

目标删除haha.docx

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class IODemo11 {

    public static void main(String[] args) {

        System.out.println("请输入根目录:");
        Scanner scanner = new Scanner(System.in);
        String rootName = scanner.next();
        File root = new File(rootName);
        if (!root.exists()) {
            System.out.println("没有此目录!");
            return;
        }

        System.out.println("请输入文件名字:");
        String name = scanner.next();
        // 把查到的文件放到list里
        // 有可能会有相同的文件名在不同的文件夹下面,或者名字相同属性不同
        List<File> files = new ArrayList<>();
        descFiles(root, name, files);
        for (File file: files) {
            System.out.println("确定要删除" + file.getPath() + " ?");
            String choice = scanner.next();
            if (choice.equals("Y") || choice.equals("y")) {
                file.delete();
                System.out.println("删除成功!");
            } else {
                System.out.println("取消删除!");
            }
        }
    }

    // root:根目录   name:要删除的文件名字   files:存储要删除文件的容器
    private static void descFiles(File root, String name, List<File> files) {
        // 文件是树的方式存储的,用递归查文件

        // 先列出root下所有的文件
        File[] file = root.listFiles();

        // 如果目录是空的,就返回
        if (file == null) {
            return;
        }

        // 不是空的就依次查
        for (File x : file) {
            // 如果是目录,就递归继续查
            if (x.isDirectory()) {
                descFiles(x, name, files);
            } else {
                // 不是目录就判断是否为要删除的文件
                if (x.getName().contains(name)) {
                    // 是就存到files
                    files.add(x);
                }
            }
        }
    }

}

复制文件

import java.io.*;
import java.util.Scanner;

// 文件的复制
// 使用字节流复制
public class IODemo12 {

    public static void main(String[] args) throws IOException {

        // 源文件 + 源路径 --> 目标文件 + 目标路径
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入被复制的文件名字:");
        String srcName = scanner.next();
        System.out.println("请输入被复制文件的路径:");
        String srcPath = scanner.next();
        System.out.println("请输入复制目标路径:");
        String descPath = scanner.next();

        // 同一个文件不能复制到相同文件夹下(除非改名字)
        File descFile = new File(descPath, srcName);
        if (descFile.exists()) {
            System.out.println("要复制的文件已存在!无法复制!");
            return;
        }
        File srcFile = new File(srcPath, srcName);
        if (!srcFile.exists()) {
            System.out.println("被复制文件不存在!");
            return;
        }

        // 开始复制
        // 源文件读进来  写给目标文件
        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(descFile)) {
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    System.out.println("复制成功!");
                    break;
                }
                outputStream.write(b);
            }
        }

    }

}


有什么错误评论区指出。希望可以帮到你。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值