简单粗暴的实现一下:文件操作!

关于文件操作,笔者在前面文章中讲解了关于:文件操作和IO的文章,感兴趣的各位老铁可以看一下:文件操作和IO-CSDN博客

那么,我们来看一下今日的一个主题:

  1. 文件系统操作File类:——》文件资源管理器能干啥??这里咱们就能干啥??
  2. 文件内容操作:流对象

流对象:

字节流:InputStream    OutputStream

字符流:Reader   Writer

基本步骤:

  1. 创建对象(打开文件):指定文件路径

    绝对路径:从盘符开始

    相对路径:以“ . ”或者“ ..”开头的,必须要有一个基准目录/工作目录

  2. 读写文件:read  write

    read:一个文件读完了,就会返回-1,作为结束标志(while循环)

    read()的无参数版本,返回该字节的内容

    read(byte[] buffer , int offset , int length)读到buffer数组中,但不是从头放,是从offset位置放,最多放length这么长,返回值也是实际读的长度!!

    read(byte[] buffer)将读到的内容放到buffer数组中,返回值是读到的字节数

  3. 关闭文件:close!

文件操作案列:

扫描指定目录,并指到名称或者内容中包含指定字符的所有普通文件(不包含目录),遍历目录,在里面的文件中查找!(这个功能类似于全文检索功能),如:你在电脑上有很多目录,目录上有很多文件,假设某些文件中包含“hello world”关键字!!这个程序就是找出哪些文件是包含这个关键词的!!

那么,我们来简单粗暴的实现一下吧:

  1. 先去递归的遍历目录,如:给定一个d:/(d盘),去递归的把这里包含的文件都列出来
  2. 每次找到一个文件,都打开,并读取文件内容(得到String)
  3. 在判定要查询的词,是否在上述文件内容存在,如果存在,结果即为所求!!

上述的这种方式并不高效,小规模的搜索还是可以的!更高效的实现就要依赖“倒排索引”这样的数据结构了(高阶)!

那么,按照上述思路,我们有着下述代码:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Scanner;

public class Main {
    //简单粗暴的实现一下:文件操作!
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        //1.先让用户指定一个要搜索的根目录
        System.out.println("请输入要扫描的根目录:");
        //rootDir根目录
        File rootDir=new File(scanner.next());
        if (!rootDir.isDirectory()){
            System.out.println("输入有误,你输入的目录不存在");
            return;//目录不存在,直接返回
        }
        //2。让用户输入一个要查询的词
        System.out.println("请输入要查询的词");
        //word要查找的词
        String word=scanner.next();
        //3.递归的进行目录/文件的遍历了
        //递归是为了避免:目录里可能还包含其他目录
        scanDir(rootDir,word);
        //目录结构是“N叉树”,树本身就是递归定义的,通过递归的方式来进行处理,其实还是比较合适的!
    }
    
    private static void scanDir(File rootDir,String word){
        //列出当前的rootDir中的内容,没有内容直接递归结束
        File[] files=rootDir.listFiles();
        //rootDir.listFiles()列出目录中的内容
        if (files==null){
            //当前rootDir是一个空的目录,这里啥都没有
            //没必要往里递归了
            return;//目录里啥都没有
        }
        //目录里有内容,就遍历目录中的每个元素
        for (File f:files) {
            System.out.println("当前搜索到:" + f.getAbsolutePath());
            if (f.isFile()){
                //是普通文件
                //打开文件,读取内容,比较看是否包含上述关键词
                String content=readFile(f);
                if (content.contains(word)){
                    //如果包含,则打印…………
                    System.out.println(f.getAbsolutePath()+"包含要查找的关键字");
                }
            }else if (f.isDirectory()){
                //是目录
                //进行递归操作
                scanDir(f,word);
                //此处的递归,其实就是以当前f这个目录作为起点,在搜索里面的内容了!!
            }else {
                //不是普通文件,也不是目录文件,直接跳过(以Linux为列,就有七种文件类型!)
                continue;
            }
        }
    }
    
    private static String readFile(File f){
        //读取文件的整个内容,返回出来
        //使用字符流来读取,由于咱们匹配的是字符串,此处只能按照字符流来处理,才有意义
        StringBuilder stringBuilder=new StringBuilder();
        try(Reader reader=new FileReader(f)) {
            //一次读一个字符,把读到的结果给拼装到StringBuilder中
            //统一转成String
            while (true){
                //一次读一个字符
                int c=reader.read();
                if (c==-1){
                    break;
                }
                stringBuilder.append((char) c);
                //c 本身是int类型,我们需要强转为char类型,确保c不能超过char的数据范围!!
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}

上述的代码没有考虑到文件特别大(栈溢出),内存存不下的情况!!!

如果确实需要考虑这种情况,那么,我们将文件分块读取即可!!

对于二进制文件:难点不是读,可以很容易把每个字节都读出来!但是不同的二进制文件,里面字节的含义是不同的,不能理解这里是啥意思!!

比如:word,写个“hello word”,这个时候,可以整个word文件里都没有“hello word”,这个字符串,可能是通过其他方式转成二进制保存,这就需要你理解word的二进制格式,才能做解析,才能查找!!

你可能感兴趣的:(操作系统哪些事?,java要笑着学,java,开发语言)