Java 读写一个文件

引言

本人之前总结过一篇《Java 文件操作》博客,那篇博客更加详细。如果小伙伴遇到本篇博客不懂的地方,可以点击下方链接,去看看之前的那篇博客。

Java 文件的操作

本篇博客主要围绕着【字节流读写文件】 与 【字符流读写文件】进行展开讨论。

我们知道 Java 的读文件与写文件,都是依靠流对象来进行的,主要有【字节流】与【字符流】两类可以供我们选择,然而它们其实就是我们日常开发中,对于文件操作,最常用的选择。

一、字符流读写文件

准备工作

创建一个 TestFile2 类,里面放两个方法,一个用来读文件,一个用来写文件。
并在准备好的 " test.txt " 文件中,准备好数据。

0

字符流读文件

public class TestFile2 {
    /**
     * 将文件中的数据 " 以字符流的形式 " 读出来,再用一个字符串接收
     */
    public static String readFile(String filePath) {
        StringBuilder result = new StringBuilder();

        try (FileReader fileReader = new FileReader(filePath)) {
            while (true) {
                int ch = fileReader.read();
                if (ch == -1) {
                    break;
                }
                result.append((char)ch); // 一次拼接一个字符
            }
            return result.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
        String filePath = "D:/文件/test.txt";
        String data = TestFile2.readFile(filePath);
        System.out.println(data);
    }
}

在上面的代码中,我们需要注意几个点:

1. 我们将读到的数据,通过一个字符串接收,但是为什么不直接用 String 类型接受呢?

① 在当前场景中," fileReader.read() " 这个方法一次只读一个字符,这里 " read " 方法的无参形式也是用的最多的形式。因为你拿一个字符数组接收,你压根不知道要 new 多大的内存。但是无参形式的 " read " 方法,只要你读到末尾了,就返回 -1.

② 利用 StringBuilder 类进行拼接更合理,而不是用 String 类的加号拼接。 因为 String 类 的实例是一个不可变对象,每次利用加号拼接,就会 new 一个新的对象,这样会让代码效率变低。而 StringBuilder 类就是不断地将字符拼接到同一个对象中。

2. 本次使用流对象后,并没有使用 " close " 方法来关闭,因为我采用了 " try with resources " 语法,不理解的小伙伴,可以点击文章引言处的链接看一下。

3. 实际上 " read " 方法中可以支持很多参数,我们可以根据不同场景,根据参数读取需要的数据。但是,可想而知,字符流读文件,里面的参数要么和字符有关,要么就跟字符串有关。

展示结果:

1

字符流写文件

public class TestFile2 {
    /**
     * 将数据 " 以字符流的形式 " 写入文件
     */
    public static void writeFile(String data, String filePath) {
        // 使用 try with resource 这样的语法
        try (FileWriter fileWriter = new FileWriter(filePath)) {
            fileWriter.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String filePath = "D:/文件/test.txt";
        String data = "Welcome to the world !";
        TestFile2.writeFile(data, filePath);

    }
}

展示结果:

2

在上面的代码中,我们需要注意的事项:

1. 和前面的思想一样," write " 方法支持的传入参数有很多,我们可以根据自己的需求来设定,上面的例子,是直接将字符串写入文件,这很方便。

2. 可以看到,上面的代码直接写入了文件,但也有一个问题,它直接就将原先的文本进行了覆盖。如果不覆盖,需要拼接改怎么办呢?

使用下面代码:

try (FileWriter fileWriter = new FileWriter(filePath, true))

将上面 new 对象的第二个参数置为 true,表示可以拼接原先的文本,如果不设置,那么默认就为 false.

假设我们依照刚刚的 main 方法,再对文件进行一次写入,看看效果:

3

二、字节流读写文件

public class TestFile1 {
    /**
     * 将文件中的数据 " 以字节流的形式 " 读出来,再用一个字符串接收
     */
    public static String readFile(String filePath) {
        StringBuilder result = new StringBuilder();
        try (InputStream inputStream = new FileInputStream(filePath)) {
            while (true) {
                int ch = inputStream.read();
                if (ch == -1) {
                    break;
                }
                result.append((char) ch);
            }
            return result.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将数据 " 以字节流的形式 " 写入文件
     */
    public static void writeFile(String data, String filePath) {
        try (OutputStream outputStream = new FileOutputStream(filePath, true)) {
            outputStream.write(data.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String filePath = "D:/文件/test.txt";
//        String data = TestFile1.readFile(filePath);
//        System.out.println(data);
        String data = "hello world";
        TestFile1.writeFile(data, filePath);
    }
}

字节流和字符流的用法相似,这里就不再展示说明了。

针对上面的代码,我们需要注意的事项:

1. 字节流读写文件和字符流读写文件的思路是一样的,只是一个单位是字节,一个单位是字符而已,所以我们使用的时候,需要明确场景需要的单位。

2. 上面代码中,字节流读写文件用到的类是 InputStream 和 OutputStream,当然,也有其他的类可供使用,这里就不展开了,只要自己会用即可。

总结

1. 在上面的代码中,可以看到【字符流】与【字节流】的用法是很相似的,这就是 Java 为我们提供流思想,只是两类流对象,使用的类不同。

2. 【字符流】和【字节流】虽然有共同之处,但是在对于读写文件上的策略还是很不相同的,因为这就是两个单位不同所引发的不同之处。虽然,我们可以利用 ( byte / char ) 进行强制转换,但是我们最好不要这么做,因为这可能会造成数据丢失的情况。

3. 【字符流】常用于读写文本文件,因为文本文件,不同的操作系统可能有不同的编码,你压根不知道多少个字节对应着一个字符,所以使用对于文本文件,我们应该使用【字符流】,简单又方便。

4. 【字节流】常用于读取 HTTP 请求中的正文,对于 HTTP 协议中的 " header " 中 Content - Length,它表示正文的 " 字节数 ",我们就可以利用这一点,一次性读取所有字节的数据。

综上所述,【字符流】与【字节流】读写文件并无好坏之分,哪种场景下方便,就使用哪种方案。另外,多熟悉它们的类以及类提供的方法,也利于我们日常开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十七ing

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

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

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

打赏作者

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

抵扣说明:

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

余额充值