文件 *** 作和IO

文件 *** 作和IO,第1张

~

目录

1.文件

1.1普通文件

1.1.1硬盘

1.2目录文件

1.2.1结构

1.2.2路径

1.3文件的分类

2.java中的 *** 作文件

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.FileInputStream异常处理方式:

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之后自动关闭,下面我们会进行演示)

import java.io.FileInputStream;
//import java.io.FileNotFoundException;IOException的子类
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){
              int x=inputStream.read();
              if(x==-1){
                  //表示已经读完
                  break;
              }
              System.out.println(x);
          }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出结果: 

b.一次读多个字节

import java.io.FileInputStream;
//import java.io.FileNotFoundException;这是一个子类
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];
//读取tmp这个数组,从0开始,读两个字节的长度
              int x=inputStream.read(tmp,0,2);
              if(x==-1){
                  //表示已经读完
                  break;
              }
             for(int i=0;i

 结果如下:

③通过Reader来读取文件
a.一个字符一个字符读

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
public class demo2 {
    public static void main(String[] args)  {
        try(Reader reader=new FileReader("C:\Users\张洋洋的小布偶\Desktop/test.txt")){
            while(true){
                int x= reader.read();
                if(x==-1){
                    break;
                }
                System.out.println(x);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

 b.多个字符读:

import java.io.FileNotFoundException;
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[]tmp=new char[1024];
    int x=reader.read(tmp);
    if (x==-1){
        //读完了
        break;
    }
    String ret=new String(tmp,0,x);
    System.out.println(ret);
}
} catch (IOException e) {
    e.printStackTrace();
}
    }
}

结果如下:

2.2.3写文件

①OutputStream来写文件

a.一次写一个字节:

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(97);
            outputStream.write(97);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 b.一次写多个字节:

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");){
            byte[]tmp=new byte[]{97,98,98,97};
            //从0开始,写2个
            outputStream.write(tmp,0,2);
          //  outputStream.write(tmp);
        } 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.util.Scanner;
public class demo3 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        //输入待扫描的路径
        System.out.println("请输入待扫描的路径:");
        String dath=input.next();
        //输入待删除的文件名
        System.out.println("请输入待删除的文件名:");
        String nameDelete=input.next();
        //构建一个文件对象进行 *** 作
        File rootDir=new File(dath);
        //判断此时的路径是不是一个目录,因为不可能直接是一个文件,那么这样的搜索是毫无意义的
        if(!rootDir.isDirectory()){
            //如果不是一个目录,那么说明输入有误,直接退出
            System.out.println("输入有误!!!");
            return;
        }
        //如果无误,那么遍历这个文件
        findDir(rootDir,nameDelete);
    }
    public static void findDir(File rootDir,String namedelete){
        File[]file=rootDir.listFiles();
        if(file==null){
            //表明是空目录
            return;
        } //不是空目录就遍历此目录里面的所有内容,如果是普通文件就看是不是要删除的文件,不是文件是目录的话,就再遍历这个目录
        for(File f : file){//列出rootDir里面有什么内容
            if(!f.isFile()){//该目录中没有文件
                findDir(f,namedelete);//进一步在这一层的基础上进行递归
            }
            if(f.isFile()){//该目录中有文件,那么我们来判断文件中是否包含关键字
                if(f.getName().contains(namedelete)){
                    //不要求名字完全一样,只要文件名中包含了关键字就可以删除
                    //进行删除 *** 作
                    deleteFile(f);
                }
            }
        }
    }
    public static  void deleteFile(File f){
        //获取该文件的绝对路径
        System.out.println(f.getAbsolutePath() + "确认要删除文件吗(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("文件放弃删除");
        }
    }
}

③输出结果:

3.2普通文件的复制

①思路:

我们先输入需要拷贝文件的路径,输入无误找到后,对文件中的内容进行一个拷贝

②代码:(注意复制文件的时候会自动地创建文件)

import java.io.*;
import java.util.Scanner;
//实现查找文件并删除文件
public class demo2 {
    public static void main(String[] args) {
        //输入需要待拷贝文件的原路径
        Scanner input=new Scanner(System.in);
        System.out.println("输入需要复制文件的路径:");
        String copyDath=input.next();
        //请输入需要拷贝到哪个路径
        System.out.println("请输入需要拷贝到哪个路径:");
        String prepareDath=input.next();
        File file=new File(copyDath);
        //判断路径是否正确
        if(!file.isFile()){
            System.out.println("输入路径有误");
            return;
        }
        //如果输入路径无误的话,我们就需要把内容拷贝过去
       try(InputStream inputStream=new FileInputStream(copyDath)){
           try(OutputStream outputStream=new FileOutputStream(prepareDath)){
               byte[]tmp=new byte[1024];
               while(true){
                   int x=inputStream.read(tmp);
                   if(x==-1){
                       break;
                   }
                   outputStream.write(tmp,0,x);
               }
           }
       }catch (IOException e) {
           e.printStackTrace();
       }
    }
}

③输出结果:

  

3.3文件内容的查找

①思想:递归

遍历目录找含有该关键字的文件。与案例3.1很相似

②代码:

import java.io.*;
import java.util.Scanner;
public class demo1 {
    public static void main(String[] args) throws IOException {
        //输入要扫描的文件路径
        Scanner input=new Scanner(System.in);
        System.out.println("输入要扫描的文件路径:");
        String dath=input.next();
        //输入待搜索的关键字
        System.out.println("输入要查找的关键字:");
        String ret=input.next();
        File f=new File(dath);
        //判断是否存在该目录
        if(!f.isDirectory()){
            System.out.println("输入路径有误");
            return;
        }//若是无误
        sDir(f,ret);
    }
    public static void sDir(File f,String ret) throws IOException {
        File []files=f.listFiles();
        if(files==null){
            return;
        }
        for (File f1:files) {
            //若是此层没有查找到,但是仍有目录,则继续递归
            if(f1.isDirectory()){
                sDir(f1,ret);
            }
            if(f1.isFile()){
                //针对文件进行查找
                if(containsWord(f1,ret)){
                    System.out.println(f.getCanonicalPath());
                }
            }

        }
    }//判断是否存在关键字
    public static boolean containsWord(File f,String ret) {
        StringBuilder stringBuilder = new StringBuilder();
        try (Reader reader = new FileReader(f)) {
            char[] tmp = new char[1024];
            while (true) {
                int x = reader.read(tmp);//read方法读到的是它的个数
                if (x == -1) {
                    break;
                }
                //进行对每次读取的内容进行拼接
                stringBuilder.append(tmp,0,x);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //indexOf返回的是子串的下标,如果word存在,那么下标一定不是-1,
        return stringBuilder.indexOf(ret) != -1;
    }
}

③输出结果:

感谢观看鸭~~~

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/724679.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-26
下一篇2022-04-26

发表评论

登录后才能评论

评论列表(0条)