【浅学Java】文件操作和IO

1. 关于文件的一些基本概念

在这里插入图片描述

2. Java中的操作文件

构造方法:
在这里插入图片描述
方法:
在这里插入图片描述

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

        File file = new File("./test1.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());//修饰过的绝对路径,去掉了一些 ././
    }
}

3. 文件内容的读写 —— 数据流

3.1 从文件中读数据(InputStream)

1. 逐个字节读(无汉字)

public class FileDemo9 {
    public static void main(String[] args) throws IOException {
        InputStream inputStream=null;
        try{
            //1.这个创建实例的过程就相当于打开文件
            inputStream = new FileInputStream("./test1.txt");
            //2.逐个字节的读取出文件内容
            while(true){
                int b=inputStream.read();
                if(b==-1){
                    break;
                }
                System.out.printf("%c", b);//注意:这里用的是printf
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //3.关闭文件,如果不关闭就容易造成资源泄露
            inputStream.close();
        }
    }
}

在这里插入图片描述

2. 一次读取多个字节(无汉字)

public class FileDemo11 {
    public static void main(String[] args) {
        //一次读取 1024 个字节
        try(InputStream inputStream = new FileInputStream("./test1.txt")){
            byte[] buffer  = new byte[1024];
            while(true){
                int len=inputStream.read(buffer);//返回的是读取到的字节数
                //读到文件结尾的时候,就会返回-1
                if(len==-1){
                    break;
                }
                for(int i=0;i<len;i++){
                    System.out.printf("%c",buffer[i]);
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

3.当读取文件中有汉字时

在这里插入图片描述

public class FileDemo12 {
    public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("./test1.txt")){
            try(Scanner scanner =new Scanner(inputStream,"UTF-8");){
                while (scanner.hasNext()){
                    String s =scanner.next();
                    System.out.print(s);//注意:这里是print
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

3.2 往文件中写入数据(OutputStream)

1. 几种常规写入方式

public class FileDemo13 {
    public static void main(String[] args) {
        //一旦按照OutputStream的形式打开文件,就会把文件原来的内容给清空
        try(OutputStream outputStream = new FileOutputStream("./test1.txt")){
            //写入一个字符
            outputStream.write('a');

            //按照字节来写入
            byte[] buffer = new byte[]{(byte)'a',(byte)'b',(byte)'c',(byte)'d',(byte)'e'};
            outputStream.write(buffer);

            //按照字符串写入
            String s = "hello world";
            outputStream.write(s.getBytes());//s.getBytes(),将s转为一个字节数组

            //刷新
            outputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

2. 用 PrintWriter 进行写入

public class FileDemo14 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("./test1.txt")){
            try(PrintWriter writer = new PrintWriter(outputStream)){//于Scanner的定位类似
                writer.println("hello world");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

3. 关于 flush() 刷新缓冲区

缓冲区的设置是为了提高计算机读写时的效率。

在把内存上的东西写入到磁盘时,计算机读写内存的速度时比较快的,但是读写磁盘的速度是比较慢的,这个速度不匹配的问题是会影响工作效率的,所以就引入了缓冲区,减少直接对磁盘的访问次数,那是如何减少的呢?

计算机从内存中放到的数据先放到缓冲区,等到缓冲区满了之后,再把缓冲区中的内容送到磁盘

3.3 什么样的类能放到try()里面呢?

在这里插入图片描述
以上面放入到try()当中的InputStream 和 OutputStream 做展示

3.4 未及时close导致的资源泄漏问题

4. 文件操作案例

案例1

案例描述:扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件

代码实现

public class FileDemo15 {
    public static void main(String[] args) throws IOException {
        //1.让用户输入一个目录 和 要查询的关键字
        System.out.println("请输入要扫描的目录:");
        Scanner scanner = new Scanner(System.in);
        String root =scanner.next();
        File rootDir= new File(root);
        if(!rootDir.isDirectory()){
            System.out.println("您输入的路径错误,程序退出!");
            return;
        }
        System.out.println("请输入要查找的文件名中包含的关键词:");
        String token = scanner.next();

        //2.递归遍历查找
        List<File> result = new ArrayList<>();//表示递归遍历的结果,包含所有带有token该关键字的文件名
        scanDir(rootDir,token,result);

        //3.遍历result,用用户是否要删除文件,根据用户的输入决定是否删除
        for(File f:result){
            System.out.println(f.getCanonicalPath()+"是否要删除?(Y/N)");
            String input = scanner.next();
            if(input.equals("Y")){
                f.delete();
                System.out.println("删除成功!");
            }
        }

    }
    private static void scanDir(File rootDir,String token,List<File> result) throws IOException {
        // list 返回的是一个String类型的文件名,使用listFiles直接得到的就是File对象
        File[] files = rootDir.listFiles();
        if(files==null||files.length==0){//当前目录是一个空的目录
            return;
        }
        for(File f:files){
            if(f.isDirectory()){
                //如果当前文件是一个目录,就继续递归
                scanDir(f,token,result);
            }
            else{
                //当前文件是一个普通文件,就判断一下这个文件是否包含了待查找的关键字
                if(f.getName().contains(token)){
                    result.add(f.getCanonicalFile());
                }
            }
        }
    }
}

案例2

进行普通文件的复制

public class FileDemo16 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要复制的文件路径(绝对路径):");
        String sourcePath=scanner.next();
        File sourceFile = new File(sourcePath);
        if(!sourceFile.isFile()){
            System.out.println("文件路径错误,程序直接退出");
            return;
        }
        System.out.println("请输入目标目录路径(绝对路径):");
        String targetPath=scanner.next();
        File targeFile=new File(targetPath);
        if(targeFile.exists()){
            System.out.println("目标文件已经存在,程序直接退出");
            return;
        }
        if(!targeFile.getParentFile().exists()){
            //目标文件的父目录不存在,就退出
            System.out.println("目标文件的父目录不存在,程序直接退出");
        }

        try(InputStream inputStream = new FileInputStream(sourceFile);
            OutputStream outputStream = new FileOutputStream(targeFile)){
            //从inputStream中读取,写入到outputStream
            while(true){
                byte[] buffer = new byte[1024];
                int len = inputStream.read(buffer);
                if(len==-1){
                    break;
                }
                outputStream.write(buffer,0,len);
            }
            outputStream.flush();
        }catch(IOException e){
            e.printStackTrace();
        }
        System.out.println("复制成功");
    }
}

案例3

扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

public class FileDemo17 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        //1.用户输入一个路径,待搜索的路径
        System.out.println("请输入要查找的目录:");
        String rootDir = scanner.next();
        File rootFile = new File(rootDir);
        if(!rootFile.isDirectory()){
            System.out.println("该目录不存在,或者不是文件,程序直接退出!!");
            return;
        }
        //2.再让用户输入一个查询词,表示要查找的内容
        System.out.println("请输入你要查找的词:");
        String query = scanner.next();
        //3.遍历目录以及文件,进行匹配
        List<File> result = new ArrayList<>();
        scanDirWithContent(rootFile,query,result);
        //4.把路径打印出来
        for(File f :result){
            System.out.println(f.getCanonicalPath());
        }
    }
    private static void scanDirWithContent(File rootFile,String query,List<File> result){
        File[] files = rootFile.listFiles();
        if(files==null||files.length==0){
            //针对空的目录直接返回
            return;
        }
        for(File f:files){
            if(f.isDirectory()){
                scanDirWithContent(f,query,result);
            }else{
                if(f.getName().contains(query)){//看看文件名称是否包含
                    result.add(f);
                }else if(isContentContains(f,query)){//看看文件内容是否包含
                    result.add(f);
                }
            }
        }
    }
    private static boolean isContentContains(File f,String query){
        StringBuilder stringBuilder = new StringBuilder();
        //打开 f 这个文件,依次取出每一行结果,去和 query 进行一个 indexof
        try(InputStream inputStream = new FileInputStream(f)){
            Scanner scanner= new Scanner(inputStream,"UTF-8");
            while(scanner.hasNextLine()){
                String line=scanner.nextLine();
                stringBuilder.append(line+'\n');
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return stringBuilder.indexOf(query)!=-1;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值