File(文件)和 IO(读写文件)

一、文件的一些知识

1、概念

狭义的文件:硬盘上的 文件 和 目录(文件夹)。

广义的文件:计算机中的很多 软硬件资源。操作系统中,把很多硬件设备和软件资源抽象成了文件,按照文件的方式统一管理。(如:网卡。操作系统把网卡也当成文件)

本文章只讨论狭义的文件。

2、文件的路径

绝对路径:以 C: D: c: d: 这样的盘符开头的路径

相对路径:以当前所在的目录(工作目录)为基准,以 . 或者 .. 开头(. 有时候可以省略)的路径( . 表示当前目录, .. 表示回退到前一个目录)

如:文件a 的路径是 D:/tmp/a   那么,

如果工作目录是 D:/   相对路径就是 ./tmp/a

如果工作目录是 D:/tmp   相对路径就是 ./a

如果工作目录是 D:/tmp/b   相对路径就是 ../a

3、文件的分类

(1)文本文件:存的是文本,字符串,用记事本打开能看懂

(2)二进制文件:存的是二进制数据,用记事本打开看不懂,是乱码

二、Java对于文件系统的操作

Java标准库,提供了 File 这个类,用来对文件系统进行操作(文件的创建,删除,重命名....等)。

1、构造方法:

File(File parent,String child)

File(String pathname)

File(String parent,String child)

参数是绝对路径,相对路径都可以,parent 表示当前文件所在的目录,child表示文件名

2、方法

(1)

返回类型方法说明
StringgetParent()返回 File的 目录
StringgetName()返回 File的 文件名
StringgetPath()返回 File的 路径
StringgetAbsolutePath()返回 File的 (和路径拼接的)绝对路径
StringgetCanonicalPath()返回 File的 (正确的)绝对路径
 public static void main(String[] args) throws IOException {
        //不要求d:/这里真的有个test.txt
        File file = new File("d:/test.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());
}
public static void main(String[] args) throws IOException {
        //不要求d:/这里真的有个test.txt
        File file = new File("./test.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());
}

(2)

返回类型方法说明
booleancreateNewFile()真的创建一个文件
booleanexists()判断文件是否真实存在
booleanisFile()判断文件是否是一个普通文件
booleanisDirectory()判断文件是否是一个目录
booleandelete()删除一个文件
voiddeleteOnExit()程序退出的时候会自动删除这个文件
booleanmkdir()真的创建一个目录(只能创建一级目录)
booleanmkdirs()创建多级目录
public static void main(String[] args) throws IOException {
        File file = new File("./test.txt");
        //真的创建一个文件
        file.createNewFile();
        //判断文件是否真实存在
        System.out.println(file.exists());
        //判断文件是否是一个普通文件
        System.out.println(file.isFile());
        //判断文件是否是一个目录
        System.out.println(file.isDirectory());
       //删除这个文件
        file.delete();
}
  public static void main(String[] args) {
        File dir = new File("./test");
        //真的创建一个目录,只能创建一级目录
        dir.mkdir();
        File dir2 = new File("./aaa/bbb/ccc");
        //创建多级目录
        dir2.mkdirs();
}

三、 Java对于文件内容的操作

Java标准库,提供了 字节流和字符流 两种类,用来对文件内容进行操作(文件的读和写),称为“流对象”(我们把读写文件的对象称为流对象)。

字节流:以字节为单位,读写数据,适合操作二进制数据。 InputStream FileInputStream 和 OutputStream FileOutputStream

字符流:以字符为单位,读写数据,适合操作文本数据。 Reader FileReader 和 Writer FileWriter

使用步骤:

1、打开文件(也就是构造对象)这个文件存在才能构造成功

2、文件(针对 InputStream/Reader文件(针对 OutputStream/Writer

3、关闭文件(close)

1、InputStream —— 往内存中读

返回类型方法说明
intread()一次读取一个字节并把读到的返回,返回-1说明读完了
intread(byte[] b)

把读到的内容尽可能填充到参数的这个字节数组中(使用参数来接收内容,尽可能把数组填满),

返回值是实际读取的字节数,返回-1 代表读完了

intread(byte[] b,int off,int len)和2类似,只不过是往数组的一部分区间里尽可能填充,
最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返
实际读取的字节数,返回 -1 代表读完了
voidclose()关闭字节流

不带参数的read:

一次读取一个字节,并把读到的字节返回,返回-1说明文件读完了。

 public static void main(String[] args) throws IOException {
        //1、构造对象,也就是打开文件
       InputStream inputStream = new FileInputStream("d:/test.txt");
        //2、读取文件
        while(true){
            //一次读取一个字节,返回读取到的字节
            int b = inputStream.read();

            if(b == -1){
                break;
            }
            System.out.printf("%x\n",(byte)b);
        }
        // 3、关闭文件
        inputStream.close();
}

 带一个参数的read:

参数是一个 byte类型的数组,用来存放读到的内容,每一次读都会尽可能的读数组大小的字节来把数组填满。如果不够,有多少就读多少,会返回实际读取的字节数。文件读完了,会返回-1.

public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("d:/test.txt");
        while(true){
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            System.out.println("len:"+len);
            if(len == -1){
                break;
            }
            //此时,读取的结果就被方法buffer中了
            for (int i = 0; i < len; i++) {
                System.out.printf("%x\n",buffer[i]);
            }
        }
        inputStream.close();
}

2、OutputStream —— 往硬盘中写

返回类型方法说明
voidwrite(int b)一次写一个字节
voidwrite(byte[] b)把字符数组b里的内容写进去
intwrite(byte[] b, int off,
int len)
从字符数组b的off位置开始往文件里写,写len个字节
voidclose()关闭字节流

对于OutputStream来说,默认情况下,打开一个文件,会先清空文件的原有内容。 

而且,如果读的文件不存在,在父路径正确的情况下,会自己创建一个文件。

如果没有执行到close,一直打开文件不关闭,可能会出现文件描述符表被占满的情况。

下面这个写法更推荐:

public static void main(String[] args) throws IOException {
       try(OutputStream outputStream = new FileOutputStream("d:/test.txt")){
           outputStream.write(97);
           outputStream.write(98);
           outputStream.write(99);
           outputStream.write(100);
       }
}

这个写法虽然没有显示的写close,实际上是会执行的。 只要 try 语句块执行完毕,就可以自动执行到 close。这个语法在Java中被称为 try with resources

3、Reader

和字节流用法差不多

public static void main(String[] args) {
        try(Reader reader = new FileReader("d:/test.txt")){
            while(true){
               int ch = reader.read();
               if(ch == -1){
                   break;
               }
                System.out.println(""+(char)ch);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
}

4、Writer

和字节流用法差不多

对于Writer来说,默认情况下,打开一个文件,会先清空文件的原有内容。 

而且,如果读的文件不存在,在父路径正确的情况下,会自己创建一个文件。

public static void main(String[] args) {
        try(Writer writer = new FileWriter("d:/test.txt")){
            writer.write("hello world");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
}

四、练习

1、查询指定目录(包括它的子目录)下有没有要删除的普通文件,有的话就删除

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

//指定目录下删除指定文件
public class IODemo10 {
    private static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println("请输入一个目录:");
        String dir = scanner.next();
        File root = new File(dir);
        if(!root.isDirectory()){
            System.out.println("输入有误");
            return;
        }
        System.out.println("请输入要删除的文件名");
        String delete = scanner.next();
        search(root,delete);
    }

    private static void search(File root, String delete) {
        System.out.println(root.getAbsolutePath());
        if(root == null){
            return;
        }
        File[] files = root.listFiles();
        for (File file:files) {
            if(file.isDirectory()){
                //如果是目录
                search(file,delete);
            }else{
                //如果是文件
                if(file.getName().contains(delete)){
                    System.out.println("确定要删除"+file.getAbsolutePath()+"这个文件吗?");
                    String choice = scanner.next();
                    if(choice.equals("Y")||choice.equals("y")){
                        file.delete();
                        System.out.println("删除成功!");
                    }else{
                        System.out.println("删除取消!");
                    }
                }
            }
        }
    }
}

2、文件的复制:把一个文件拷贝成另一个文件

把第一个文件按照字节依次读取,写到第二个文件中。

第二个文件不存在,会自己创建。

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

//文件的复制
public class IODemo11 {
    public static void main(String[] args) {
        //输入两个路径:源 和 目标(从哪里考,拷贝到哪里)
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入源路径:");
        String src = scanner.next();
        File srcFile = new File(src);

        System.out.println("请输入目标路径:");
        String desc = scanner.next();
        File descFile = new File(desc);

        if(!srcFile.isFile()){
            System.out.println("源路径有误!");
            return;
        }
        if(descFile.isFile()){
            System.out.println("目标路径有误!");
            return;
        }
        //开始拷贝
        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(descFile)){
            //进行读文件操作
            while(true){
              int b = inputStream.read();
              if(b == -1){
                  break;
              }
              outputStream.write(b);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值