【Java EE】文件内容的读写——数据流

目录

1.InputStream概述

1.1方法

2.FileInputStream概述

2.1构造方法

2.2代码示例

2.3.利用Scanner进行字符读取

3.OutputStream概述

3.1方法

3.2利用OutputStreamWriter进行字符写入

3.3利用PrintWriter找到我们熟悉的方法


1.InputStream概述

1.1方法
修饰符及返回值类型 方法签名 说明
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

2.FileInputStream概述

2.1构造方法
签名 说明
FileInputStream(File file) 利用File构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流
2.2代码示例

示例1

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

java 复制代码
import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
public class Main {
 public static void main(String[] args) throws IOException {
 try (InputStream is = new FileInputStream("hello.txt")) {
 while (true) {
 int b = is.read();
 if (b == -1) {
 // 代表⽂件已经全部读完
 break;
 }
 
 System.out.printf("%c", b);
 }
 }
 }
}
java 复制代码
import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
public class Main {
 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;
 }
 
 for (int i = 0; i < len; i++) {
 System.out.printf("%c", buf[i]);
 }
 }
 }
 }
}

示例2

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

注意:这里我们用了这几个中文的UTF-8编码后长度刚好是3个字节和长度不超过1024字节的现状,但这种方式并不是通用的。

java 复制代码
import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "你好中国" 的内容
public class Main {
 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);
 }
 }
}
}
}
2.3.利用Scanner进行字符读取

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

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

示例1

java 复制代码
import java.io.*;
import java.util.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "你好中国" 的内容
public class Main {
 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);
 }
 }
 }
 }
}

3.OutputStream概述

3.1方法
修饰符及返回值类型 方法签名 说明
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(刷新)操作,将数据刷到设备中。

说明

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

3.2利用OutputStreamWriter进行字符写入

示例1

java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 os.write('H');
 os.write('e');
 os.write('l');
 os.write('l');
 os.write('o');
 // 不要忘记 flush
 os.flush();
 }
 }
}
java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 byte[] b = new byte[] {
 (byte)'G', (byte)'o', (byte)'o', (byte)'d'
 };
 os.write(b);
 
 // 不要忘记 flush
 os.flush();
 }
 }
}
java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 byte[] b = new byte[] {
 (byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B', (byte)'a'
 };
 os.write(b, 0, 4);
 
 // 不要忘记 flush
 os.flush();
 }
 }
}
java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 String s = "Nothing";
 byte[] b = s.getBytes();
 os.write(b);
 
 // 不要忘记 flush
 os.flush();
}
}
}
java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 String s = "你好中国";
 byte[] b = s.getBytes("utf-8");
 os.write(b);
 
 // 不要忘记 flush
 os.flush();
 }
 }
}
3.3利用PrintWriter找到我们熟悉的方法

上述,我们其实已经完成输出工作,但总是有所不方便,我们接下来将OutputStream处理下,使用PrintWriter类中完成输出,因为 PrintWriter类中提供了我们熟悉的print/println/printf方法

java 复制代码
outputStream os = ...;
OutputStreamWriter osWriter = new OutputStreamWriter(os, "utf-8"); // 告诉
PrintWriter writer = new PrintWriter(osWriter);
// 接下来我们就可以⽅便的使⽤ writer 提供的各种⽅法了
writer.print("Hello");
writer.println("你好");
writer.printf("%d: %s\n", 1, "没什么");
// 不要忘记 flush
writer.flush();

示例1

java 复制代码
import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
 try (OutputStream os = new FileOutputStream("output.txt")) {
 try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8
 try (PrintWriter writer = new PrintWriter(osWriter)) {
 writer.println("我是第⼀⾏");
 writer.print("我的第⼆⾏\r\n");
 writer.printf("%d: 我的第三⾏\r\n", 1 + 1);
 writer.flush();
 }
 }
 }
 }
}
相关推荐
TDengine (老段)10 分钟前
两分钟掌握 TDengine 全部写入方式
大数据·数据库·时序数据库·tdengine·涛思数据
Cosmoshhhyyy20 分钟前
LeetCode:3083. 字符串及其反转中是否存在同一子字符串(哈希 Java)
java·leetcode·哈希算法
AI人H哥会Java34 分钟前
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
java·开发语言·spring boot·后端·架构
开心工作室_kaic43 分钟前
springboot493基于java的美食信息推荐系统的设计与实现(论文+源码)_kaic
java·开发语言·美食
缺少动力的火车1 小时前
Java前端基础—HTML
java·前端·html
loop lee1 小时前
Redis - Token & JWT 概念解析及双token实现分布式session存储实战
java·redis
ThetaarSofVenice1 小时前
能省一点是一点 - 享元模式(Flyweight Pattern)
java·设计模式·享元模式
InSighT__1 小时前
设计模式与游戏完美开发(2)
java·游戏·设计模式
神仙别闹1 小时前
基于Java2D和Java3D实现的(GUI)图形编辑系统
java·开发语言·3d