【编程必备知识】文件内容的读写

文章目录

  • 前言
  • 1. 数据流
  • 2. Java IO 流
  • 3. InputStream 概述
    • 3.1 FileInputStream 概述
      • 3.1.1 代码示例
    • 3.2 利用 Scanner 进行字符读取
  • 4. OutputStream 概述
    • 4.1 利用 OutputStreamWriter 进行字符写入
  • 总结


前言

书接上回, 本文继续讲解关于文件的知识, 上文讲了如何对文件系统进行操作, 本文则重点讲述如何对文件内容进行读写, 要讲到两个数据流, 字符流和字节流.

关注收藏, 开始学习吧


1. 数据流

【编程必备知识】文件内容的读写_第1张图片
文件这里的内容本质上是来自于硬盘, 硬盘又是操作系统管理的. 使用某个编程语言操作文件, 本质上都是需要调用系统的 api.

虽然不同的编程语言, 操作文件的 api 有所差别, 但是基本步骤都是一样的, 文件内容的操作核心步骤简单来说, 其实就只有以下四点:

  1. 打开文件
  2. 读文件
  3. 写文件
  4. 关闭文件

2. Java IO 流

在 Java 中, IO 操作是依靠一系列类来完成的.

字节流

  • InputStream
  • OutputStream
  • 以操作字节为单位 (操作二进制文件)

字符流

  • Reader
  • Writer
  • 以操作字符为单位 (操作文本文件)

Java IO 流是一个比较庞大的体系, 涉及到非常多的类. 这些不同的类, 都有各自不同的特性. 但是总的来说, 使用方法都是类似的.

  • 调用构造方法, 打开文件.
  • close 方法, 关闭文件.
  • 如果衍生自 InputStream 或者 Reader, 就可以使用 read 方法来读数据.
  • 如果衍生自 OutputStream 或者 Writer, 就可以使用 write 方法来写数据.

3. InputStream 概述

成员方法

修饰符及返回值类型 方法签名 说明
int read() 读取一个字节的数据,返回 -1 代表已经完全读完了
int read(byte[] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了
int read(byte[] b,int off, int len) 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
void close() 关闭字节流

说明
InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream.

3.1 FileInputStream 概述

构造方法

签名 说明
FileInputStream(File file) 利用 File 构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流

3.1.1 代码示例

示例1

将文件完全读完的两种方式。相比较而言,后一种的 IO 次数更少,性能更好。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test1 {
	// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "hellotest" 的内容
    public static void main(String[] args) throws IOException {
        try (InputStream inputStream = new FileInputStream("hello.txt")) {
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    break;
                }

                System.out.printf("%c", b);
            }
        }
    }
}

采用 byte 数组来存储, 一次性读取 1024, 比前一种方法一个一个读效率更高.

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test1 {
        public static void main(String[] args) throws IOException {
        try (InputStream inputStream = new FileInputStream("./hello.txt")) {
            while (true) {
                byte[] buf = new byte[1024];
                int b = inputStream.read(buf);
                if (b == -1) {
                    break;
                }

                for (int i = 0; i < b; i++) {
                    System.out.printf("%c", buf[i]);
                }
            }
        }
    }
}

示例2

这里我们把文件内容中填充中文看看,注意,写中文的时候使用 UTF-8 编码. hello.txt 中填写 “你好中国”

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test2 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            byte[] buf = new byte[1024];
            int len;
            while (true) {
                len = is.read(buf);
                if (len == -1) {
                    // 代表文件已经全部读完
                    break;
                }
                // 每次使用 3 字节进行 utf-8 解码,得到中文字符
                // 利用 String 中的构造方法完成
                // 这个方法了解下即可,不是通用的解决办法
                for (int i = 0; i < len; i += 3) {
                    String s = new String(buf, i, 3, "UTF-8");
                    System.out.printf("%s", s);
                }
            }
        }
    }
}

3.2 利用 Scanner 进行字符读取

上述例子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类。

构造方法 说明
Scanner(InputStream is, String charset) 使用 charset 字符集进行 is 的扫描读取

示例1

import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Test3 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
           try (Scanner scanner = new Scanner(is, "UTF-8")) {
               while (scanner.hasNext()) {
                   String s = scanner.next();
                   System.out.print(s);
               }
           }
       }
   }
}

4. OutputStream 概述

成员方法

修饰符及返回值类型 方法签名 说明
void write(int b) 写入要给字节的数据
void write(byte[]b) 将 b 这个字符数组中的数据全部写入 os 中
int write(byte[]b, int off,int len) 将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
void close() 关闭字节流
void flush() 我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。

说明

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream。

4.1 利用 OutputStreamWriter 进行字符写入

示例1

public class Demo9 {
    public static void main(String[] args) throws IOException {
        try (Writer writer = new FileWriter("./test.txt", true)) {
            writer.write("hello world!");
        }
    }
}

注意, 在进行写入时, 默认是覆盖源文件内容, 如果在参数中加上 true, 则是在源文件内容后直接写入.


总结

✨ 本文主要讲述了如何对文件内容进行读写, 主要讲了字节流的两个类 InputStreamOutputStream, 字符流就不在这里仔细讲述了, 因为具体用法与字节流几乎一致, 只不过对处理的文件不同.
✨ 想了解更多知识, 请持续关注博主, 本人会不断更新学习记录, 跟随我一起不断学习.
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习.

再次感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!

你可能感兴趣的:(服务器,linux,数据库,文件IO,java)