Java 读写一个文件

简介: Java 读写一个文件

引言



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


Java 文件的操作


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

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


一、字符流读写文件



准备工作


创建一个 TestFile2 类,里面放两个方法,一个用来读文件,一个用来写文件。

并在准备好的 " test.txt " 文件中,准备好数据。


736a4fff0b584c05a2d4241ca96902a6.png


字符流读文件


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 " 方法中可以支持很多参数,我们可以根据不同场景,根据参数读取需要的数据。但是,可想而知,字符流读文件,里面的参数要么和字符有关,要么就跟字符串有关。


展示结果:


3e6ad45443984862b912c494477bd76b.png


字符流写文件


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);
    }
}


展示结果:


fb35acb95aaa4bd6a14568bd975d41c4.png


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


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


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


使用下面代码:


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


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


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


94f3badf4c5c4d199065ddd9902244b6.png


二、字节流读写文件



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,它表示正文的 " 字节数 ",我们就可以利用这一点,一次性读取所有字节的数据。


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


目录
相关文章
|
23天前
|
Java
有关Java发送邮件信息(支持附件、html文件模板发送)
有关Java发送邮件信息(支持附件、html文件模板发送)
25 1
|
27天前
|
Java
java中替换文件内容
java中替换文件内容
13 1
|
29天前
|
Java API
Java中文件与输入输出
Java中文件与输入输出
|
29天前
|
Java
java实现遍历树形菜单方法——映射文件VoteTree.hbm.xml
java实现遍历树形菜单方法——映射文件VoteTree.hbm.xml
9 0
|
1月前
|
Java
java程序导出堆文件
java程序导出堆文件
|
1月前
|
SQL Oracle Java
sql文件批处理程序-java桌面应用
sql文件批处理程序-java桌面应用
25 0
|
1月前
|
存储 Java 文件存储
如何用 Java 压缩 ZIP 文件?
【2月更文挑战第21天】
29 1
|
1月前
|
Java
Java实现文件和目录的管理
Java实现文件和目录的管理
24 0
|
25天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
90 3
|
28天前
|
Java
使用java将字符串写入到指定的文件中
使用java将字符串写入到指定的文件中
11 0