【JavaEE学习日记】----文件操作和IO下

这篇博客详细介绍了JavaEE中文件操作的概念,包括为何将文件内容视为流对象,以及InputStream、OutputStream、Reader和Writer四个类的具体使用。博主通过实例展示了如何进行文件的读写,强调了字节流和字符流的区别,以及文件内容操作可能涉及的注意事项,如写操作会清空原有文件内容。

目录

1.文件内容的操作

为什么文件内容要称为流对象?

2.四个类的具体使用

2.1InputStream

 2.2OutputStream

 2.3.Reader

2.4Writer

3.文件内容操作的三个实例


1.文件内容的操作

  • 打开文件
  • 读文件
  • 写文件
  • 关闭文件

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

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

1)读:InputStream---------》FileInputStream

2)写:OutputStream---------》FileOutputStream

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

1)读:Reader---------》FileReader

2)写:Writer---------》FileWriter

为什么文件内容要称为流对象?

这里的流Stream其实是一个形象的比喻,此处我们说的流就像水流一样源源不断的感觉

举个例子,如果想要通过水龙头接100ml水,可以一次接10ml,分十次接完,也可以一次接20ml,分5次接完,还可以一次接100ml,一次接完。这里的文件内容也是一样,想通过流对象来读取100个字节,可以一次读10个字节,分10次读完,也可以一次读20个字节,分5次读完,还可以一次读取100个字节,一次读完,当然,写文件内容也是一个道理


2.四个类的具体使用

2.1InputStream

read()提供了三个版本的重载

  • 无参数版本:一次读取一个字节,返回的值是读到这个字节
  • 一个参数版本:一次读取若干个字节,把读到的结果放到参数中指定的数组中,返回的值就是读到的字节数
  • 三个参数版本:一次读取若干个字节,把参数的结果放到指定的数组中,返回值就是读到的字节数,不是从数组的起始下标放置元素,而是从中间位置开始放元素,off表示这下标的位置,len表示最多能放多少个元素(字节)
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test1 {
    public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("d:/study.txt")) {
            //一次读取一个字节
            while (true) {
                int data = inputStream.read();
                if(data == -1){
                    break;
                }
                System.out.println(data);
            }
        }  catch (IOException e) {
            e.printStackTrace();
        }
    }
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test1 {
    public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("d:/study.txt")){
            //一次读取若干个字节
            while (true) {
                byte[] bytes = new byte[1024];
                int len = inputStream.read(bytes);
                if (len == -1) {
                    break;
                }
                String s = new String(bytes,0,len);
            }
        }  catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这里要注意的是为什么返回值的类型用int来表示:

一个字节的范围是 0 -> 255 or -128 -> 127,如果返回的是byte,本身就是-128 -> 127,当读到一个 -1 的时候,你到底是读到文件尾了,还是说正好有个字节就是-1这个值

所以未来表示这个非法状态,就约定了-1来表示,因此就需要使用一个比byte更大的范围来表示 int 或者 short

所以上述代码的-1的意思就是读到了文件末尾

 

 2.2OutputStream

 

注意:字节流的写会清空原有文件的内容!!!

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Test2 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("d:/study.txt")){
//            outputStream.write(97);
//            outputStream.write(99);
//            outputStream.write(98);
            //两种方法都可以
            byte[] data = new byte[]{97,98,99};
            outputStream.write(data);
        }  catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 2.3.Reader

字符流的读同样是包含三个方法,和字节流的用法是一样的

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Test3 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("d:/study.txt")){
            while (true) {
                //一次读取若干个字符
                char[] chars = new char[1024];
                int len = reader.read(chars);
                if(len == -1){
                    break;
                }
                String s = new String(chars,0,len);
                System.out.println(s);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.4Writer

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Test4 {
    public static void main(String[] args) {
        try(Writer writer = new FileWriter("d:/study.txt")){
//            writer.write("a");
//            writer.write("g");
//            writer.write("f");
            
            writer.write("agf");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关于字符流的操作和字节流的使用基本是一致的,文件内容的写都会使原文件内容清除


3.文件内容操作的三个实例

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

//案例1 查找文件并删除
//扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件
import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class Demo6 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要扫描的目录");
        String mainPath = sc.next();
        System.out.println("请输入包含的指定字符");
        String todeleteDir = sc.next();
        File file = new File(mainPath);
        if(!file.isDirectory()){
            System.out.println("输入有误");
            return;
        }
        // 2. 遍历目录, 把 指定目录 中的所有文件和子目录都遍历一遍, 从而找到要删除的文件
        //    通过这个方法来实现递归遍历并删除的操作
        try {
            scanDir(file,todeleteDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void scanDir(File file, String todeleteDir) throws IOException {
        //1.先列出文件中都有那些内容
        File[] files = file.listFiles();
        if (files == null) {
            //说明是一个空目录
            return;
        }
        for(File f:files){
            if(f.isFile()){
                //说明是一个文件
                if(f.getName().contains(todeleteDir)){
                    //如果包含了相同的名字就删掉
                    deletFile(f);
                }
            } else if (f.isDirectory()) {
                //说明是一个目录
                scanDir(f,todeleteDir);
            }
        }
    }

    private static void deletFile(File f) throws IOException {
        System.out.println(f.getCanonicalFile()+"Y删除 n否定");
        Scanner sc = new Scanner(System.in);
        String choice = sc.next();
        if(choice.equals("Y") || choice.equals("y")){
            f.delete();
            System.out.println("确认删除");
        }else{
            System.out.println("否定删除");
        }
    }
}

2)进行普通文件的复制

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

//普通文件的复制
//需要让用户输入两个路径,一个源路径,一个复制的路径,将源路径的文件复制到复制路径里
public class Demo7 {
    public static void main(String[] args) {
        //输入源路径
        System.out.println("输入源路径");
        Scanner scanner = new Scanner(System.in);
        String mianDirPath = scanner.next();
        System.out.println("输入目标路径");
        String dest = scanner.next();
        File file = new File(mianDirPath);
        if(!file.isFile()){
            System.out.println("源路径不对");
            return;
        }

        //先进行读
        try(InputStream inputStream = new FileInputStream(mianDirPath)) {
            //在进行写
            try(OutputStream outputStream = new FileOutputStream(dest)){
                byte[] bytes = new byte[1024];
                while (true) {
                    int len = inputStream.read(bytes);
                    if(len == -1) {
                        break;
                    }
                    outputStream.write(bytes,0,len);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

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

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

//案例三
//扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
public class Demo8 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入目录");
        String src = scanner.next();
        System.out.println("请输入要删除的关键字");
        String words = scanner.next();
        File file = new File(src);
        if(!file.isDirectory()){
            return;
        }
        scanDir(file,words);
    }

    private static void scanDir(File file, String words) {
        //先列出文件有那些内容
        File[] files = file.listFiles();
        if (files == null) {
            return;
        }
        for(File f : files){
            if(f.isFile()){
                if(containsWord(f,words)){

                }
            }else if(f.isDirectory()){
                scanDir(f,words);
            }
        }
    }

    //
    private static boolean containsWord(File f, String words) {
        StringBuilder stringBuilder = new StringBuilder();
        try(Reader reader = new FileReader(f)) {
            char[] chars = new char[1024];
            while (true) {
                int len = reader.read(chars);
                if(len == -1){
                    break;
                }
                stringBuilder.append(chars,0,-1);
            }

        }  catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.indexOf(words) != -1;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w-ib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值