目录
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();
}
}
}
}
}