文件操作和IO

~

目录

1.文件

1.1普通文件

1.1.1硬盘

1.2目录文件

1.2.1结构

1.2.2路径

1.3文件的分类

2.java中的操作文件

扫描二维码关注公众号,回复: 13865360 查看本文章

2.1文件系统的相关操作

2.2.1File类的介绍

2.2.2列出文件

2.2.3创建文件

2.2.4创建目录

2.2.5删除文件

2.2文件内容的相关操作

2.2.1打开文件

2.2.2读文件

2.2.3写文件

2.2.4关闭文件

3.文件操作的三个案例

3.1查找文件并删除

3.2普通文件的复制

3.3文件内容的查找


1.文件

我们常说的文件是存储在硬盘上的普通文件。(本节内容主要是针对普通文件进行讨论)

1.1普通文件

形如txt,jpg,mp3等存储在硬盘上的文件,被称为普通文件。

1.1.1硬盘

①机械硬盘:

a.机械硬盘的基本构造:(下面这是一张机械硬盘的简介图)

磁盘(盘片):存储数据的介质

磁头和电机:执行部分

电路板:控制部分

b.运行原理:

当机械硬盘一旦通电,里面的盘片就会高速运转,此时磁头就在盘面上找相对应的数据。但是由于机械硬盘的硬件结构是有限的,盘片转速越高,读写速度就越快,而易知盘片的速度不可能永无止境地高,所以已经有10年停滞不前了。所以引入了下面我们要谈及的固态硬盘

②固态硬盘(SSD):

这就是一个固态硬盘。

固态硬盘的硬件结构和机械硬盘截然不同,固态硬盘的读写速度要比机械硬盘快上太多。

 而我们现在主要讨论的是机械硬盘。

1.2目录文件

1.2.1结构

在计算机里,保管储存文件是通过操作系统中的“文件系统”来实现的。

而文件系统中一般是通过树形结构来组织磁盘上的目录和文件的,就是一颗N叉数

给大家举个图例看看:

这就是我们所说的树结构

1.2.2路径

①绝对路径:

绝对路径指的就是一个具体的路径,以盘符开头的。比如:C:\Program Files\Java

②相对路径:

以.或者..开头的,其中.表示当前路径

..表示当前路径的父目录(上级路径)

相对路径就必须要有一个基准目录,相对路径就是从基准目录出发,按照基准路径出发来找到相对应的文件

比如:此时的基准路径为:C:\Program Files\Java。而此时我要找javac.exe。

./javac.exe就是以上所需。. 就代表当前的基准路径

而要找到src.zip就可以这样写../src.zip。.. 就相当于回到了基准的上一层路径(C:\Program Files),再来找目标路径。

 用通俗一点的话来解释就是,绝对路径是相对于事务的整体而言的,而相对问题是相对于事务的局部而言的。

1.3文件的分类

①文本文件:

文件存储的是字符(本质上也是存储的字节,只是相邻字节刚好构成了一个个字符)。平时中类似于.txt,.c,.java这种都是文本文件。

②二进制文件:

文件存储的是字节。类似于.class,.jpg,.doc都是二进制文件

③如何区分二进制文件和文本文件:

最简单的方式是用记事本打开,如果是乱码,即是二进制文件,反之则是文本文件。

2.java中的操作文件

2.1文件系统的相关操作

是指通过文件资源管理器能够完成的一些功能,在Java中提供了File类,通过这个类来完成一系列操作,下面我们将着重讲解。

2.2.1File类的介绍

①File的构造方法:

File的构造方法,能够传入一个路径来指定一个文件,这个路径可以是绝对路径也可以是相对路径

②File的一些方法:

③我们针对其中的某些方法来进行操作演示:

代码:

import java.io.File;
import java.io.IOException;
public class demo1 {
    public static void main(String[] args) throws IOException {
        File f=new File("C:/ProgramData/test.txt");
        System.out.println("获取到文件的父目录:"+f.getParent());
        System.out.println("获取到文件名:"+f.getName());
        System.out.println("获取到文件路径:"+f.getPath());
        System.out.println("获取到文件的绝对路径:"+f.getAbsolutePath());
        //这里需要抛出一个异常,并且这里是化简过的绝对路径
        System.out.println("获取到文件的绝对路径:"+f.getCanonicalPath());
        System.out.println("===============");
        //这里的路径是一个基准路径
        File f1=new File("./ProgramData/test.txt");
        System.out.println("获取到文件的父目录:"+f1.getParent());
        System.out.println("获取到文件名:"+f1.getName());
        System.out.println("获取到文件路径:"+f1.getPath());
        System.out.println("获取到文件的绝对路径:"+f1.getAbsolutePath());
        //这里需要抛出一个异常,并且这里是化简过的绝对路径
        System.out.println("获取到文件的绝对路径:"+f1.getCanonicalPath());
    }
}

 对代码中的部分内容来进行说明:

2.2.2列出文件

代码:

import java.io.File;
import java.util.Arrays;
public class demo2 {
    public static void main(String[] args) {
        File f = new File("./");
        //查看此目录下的内容(列出目录内容)
        System.out.println(Arrays.toString(f.list()));
        //按照file对象的方法打印
        System.out.println(Arrays.toString(f.listFiles()));
    }
}

结果:

 

2.2.3创建文件

代码:

import java.io.File;
import java.io.IOException;
public class demo2 {
    public static void main(String[] args) throws IOException {
        //创建一个文件
        File f=new File("./test.txt");
        //判断文件是否存在
        System.out.println(f.exists());
        //创建文件
        f.createNewFile();
        //文件创建结束,判断是否存在
        System.out.println(f.exists());
    }
}

输出结果:

2.2.4创建目录

①创建一个目录:

代码:

import java.io.File;
import java.io.IOException;
public class demo2 {
    public static void main(String[] args) throws IOException {
        //创建一个文件
        File f=new File("./aa");
        //创建一个目录
        f.mkdir();
    }
}

结果:

②创建多个目录

代码:

import java.io.File;
import java.io.IOException;
public class demo2 {
    public static void main(String[] args) throws IOException {
        //创建一个文件
        File f=new File("./aa/bb/cc");
        //创建一个目录
        f.mkdirs();
    }
}

结果:

 

2.2.5删除文件

代码:

import java.io.File;
import java.io.IOException;
public class demo2 {
    public static void main(String[] args) throws IOException {
        //创建一个文件
        File f=new File("./test.txt");
        //判断文件是否存在
        System.out.println(f.exists());
        //删除文件
        f.delete();
        //删除文件后是否存在
        System.out.println(f.exists());
    }
}

操作结果:

2.2文件内容的相关操作

针对文件内容的读写,Java标准库提供了一组类,按照文件的内容,分成了两个系列:

①字节流对象,针对二进制文件,以字节为单位进行读写的

读:InputStream  写:OutputStream

②字符流对象,针对文本文件,是以字符为单位进行读写的

读:Reader 写:Writer

注意!!!上面这四类均是抽象类,若是我们想要实现的话需要用它们的子类

FileInputStream,FileOutputStream,FileReader,FileWriter。

这一组都是特指针对普通文件进行读写的

2.2.1打开文件

实例化对象的同时,输入指定路径,这里不详说,在代码中有体现

2.2.2读文件

InputStream和Reader均是通过read方法来读取文件,我们首先讲一下read方法:

a.无参数版本:

一次读一个字节,返回值是读到的这个字节(注意!当读到-1时,表示本文件已被读完)
b.一个参数版本:

一次读若干个字节,把读到的结果放到指定的数组中,返回值就是读到的字节数
c.三个参数版本:

一次读若干个字节,把读的结果放到参数中指定的数组中,返回值就是读到的字节数。注意!!!这里不是从数组的起始位置来对元素进行放置,而是从中间位置放置(off下标),len表示最多能放多少个元素

②通过inputStream来读取文件

a.一次读一个字节

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class demo2 {
    public static void main(String[] args) {
        InputStream inputStream = null;
        try {//创建对象,也是打开文件,有可能没有文件,因此需要抛异常
            inputStream = new FileInputStream("C:/Users/张洋洋的小布偶/Desktop/test.txt");//需要指定路径,可以是相对路径也可以是绝对路径,也可以是File对象
            //尝试一个一个字节的读,把整个文件读完
            while(true){
                int x = inputStream.read();
                if(x == -1){
                    break;//表示读完了所有的字节
                }
                System.out.println(x);//打印
            }
        } catch (IOException e) {
            //这个包含了FileNotFoundException(子类),因此可以合并,IO操作失败的可能性是非常大的
            e.printStackTrace();
        }finally {
            //读完之后需要关闭文件,释放资源
            try {
                inputStream.close();//这个放在finally里面更好有需要把定义放到外面去
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

(我们可以发现要关闭文件就要用finally,这是相当麻烦的,但与此同时,java提供了一个方法try,就可以在读取完try之后自动关闭,下面我们会进行演示)

b.一次读多个字节

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class demo2 {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("C:\\Users\\张洋洋的小布偶\\Desktop/test.txt")) {
            while (true) {
                byte[] tmp = new byte[1024];
                int x = inputStream.read(tmp);
                if (x == -1) {
                    break;//表示读完了所有的字节
                }
                for (int i = 0; i < x; i++) {
                    //打印
                    System.out.println(tmp[i]);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 结果如下:

③通过Reader来读取文件

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class demo2 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("C:\\Users\\张洋洋的小布偶\\Desktop/test.txt")) {
            while (true){
                char[] c = new char[1024];
                int x = reader.read(c);//一次读多个
                if(x == -1){
                    break;
                }
                /*for (int i = 0; i < x; i++) {
                    System.out.println(c[i]);
                }*/
                String s = new String(c,0,x);//如果传入的是byte也可以指定字符编码
                System.out.println(s);//这样也可以读
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果如下:

2.2.3写文件

①OutputStream

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class demo2 {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("C:\\Users\\张洋洋的小布偶\\Desktop/test.txt")) {
            /*outputStream.write(98);
            outputStream.write(97);一次写一个
            outputStream.write(97);*/
            //也可以一次写多个
            byte[] b = new byte[]{98,97,97};
            outputStream.write(b);//一次写多个     这里的写操作每次按照写方式打开文件,都会清空原有的文件的内容,然后再从起始位置往后写
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果如下:

 ②Writer

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class demo2 {
    public static void main(String[] args) {
        try(Writer writer = new FileWriter("C:\\Users\\张洋洋的小布偶\\Desktop/test.txt")){
            writer.write("aaa");//写操作
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果如下:

 

2.2.4关闭文件

每次读完后需要关闭文件,释放资源

3.文件操作的三个案例

3.1查找文件并删除

①思想:递归

②代码:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
//实现查找文件并删除文件
public class Demo13 {
    public static void main(String[] args) {
        //先输入要扫描的目录,以及要删除的文件名
        Scanner input = new Scanner(System.in);
        System.out.println("请输入要扫描的路径:");
        String rootDirPath = input.next();
        System.out.println("请输入要删除的文件名:");
        String toDeleteName = input.next();
        File rootDir = new File(rootDirPath);//构建文件对象
        if(!rootDir.isDirectory()){
            //不是一个目录
            System.out.println("你输入的路径有误");
            return;//可以抛一个异常
        }
        //遍历这个目录,寻找要删除的文件
        scanDir(rootDir,toDeleteName);
    }
    public static void scanDir(File rootDir,String toDeleteName){
        File[] files = rootDir.listFiles();
        if(files == null){
            //rootDir是空目录,返回
            return;
        }
        //不是空目录就遍历此目录里面的所有内容,如果是普通文件就看是不是要删除的文件,不是文件是目录的话,就再遍历这个目录
        for(File f : files){//列出rootDir里面有什么内容
            if(!f.isFile()){
                scanDir(f,toDeleteName);
            }
            if(f.isFile()){
                if(f.getName().contains(toDeleteName)){
                    //不要求名字完全一样,只要文件名中包含了关键字就可以删除
                    //进行删除操作
                    deleteFile(f);
                }
            }
        }
    }
    public static void deleteFile(File f){
        try {
            System.out.println(f.getCanonicalPath() + "确认要删除文件吗(Y/N)");
            Scanner input = new Scanner(System.in);
            String chose = input.next();
            if(chose.equals("Y") || chose.equals("y")){
                f.delete();//进行删除
                System.out.println("文件删除成功");
            }else{
                System.out.println("文件放弃删除");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.2普通文件的复制

①找到文件再进行复制

②代码:

import java.io.*;
import java.util.Scanner;
//文件复制,需要让用户支出两个文件路径,一个是原路径(被复制的文件),另一个是目标路径(复制后生成的文件)
public class Demo14 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入要拷贝的源路径:");
        String str = input.next();
        System.out.println("请输入要拷贝的目标路径:");
        String sub = input.next();
        File file = new File(str);
        if(!file.isFile()){//需要判断是不是正确的路径,目标路径不需要判断,因为没有的话,是会自己创建的
            System.out.println("不是一个正确的源路径");
            return;
        }
        //将源文件里面的内容读出来,然后再用写操作写到目标文件中去
        try(InputStream inputStream = new FileInputStream(str)) {
            try(OutputStream outputStream = new FileOutputStream(sub)) {
                byte[] b = new byte[1024];
                while(true){
                    int x = inputStream.read(b);
                    if(x == -1){
                        break;
                    }
                    outputStream.write(b,0,x);//需要指定长度,不能把所有的b都放进去
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.3文件内容的查找

①思想:递归

②代码:

import java.io.*;
import java.util.Scanner;
//进行文件内容的查找,扫描指定目录,找到名称或内容中包含指定字符的所有普通文件(不包含目录)
public class Demo15 {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入要扫描的文件路径:");
        String rootDirPath = input.next();
        System.out.println("请输入要查询的关键字:");
        String word = input.next();
        File rootDir = new File(rootDirPath);
        if(!rootDir.isDirectory()){
            System.out.println("输入的路径非法!");
            return;
        }
        sDir(rootDir,word);
    }
 
    private static void sDir(File rootDir, String word) throws IOException {
        File[] files = rootDir.listFiles();
        if(files == null){
            return;
        }
        for (File f:files) {
            if(f.isDirectory()){
                sDir(f,word);
            }
            if(f.isFile()){
                //针对文件进行查找
                if(containsWord(f,word)){
                    System.out.println(f.getCanonicalPath());
                }
            }
        }
    }
 
    private static boolean containsWord(File f, String word) {
        StringBuilder stringBuilder = new StringBuilder();
        //把f中的内容都读出来,放到StringBuilder中,看是否包含关键字
        try(Reader reader = new FileReader(f)){
            char[] c = new char[1024];
            while(true){
                int x = reader.read(c);
                if(x == -1){
                    break;
                }
                stringBuilder.append(c,0,x);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //indexOf返回的是子串的下标,如果word存在,那么下标一定不是-1,
        return stringBuilder.indexOf(word) != -1;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_58850105/article/details/124292333
今日推荐