InputStream
InputStream
并不是一个接口,而是一个抽象类,它是所有输入流的超类。
InputStream
一个最重要的方法就是int read()
,这个方法会读取输入流的下一个字节,并返回字节表示的int值(0~255)。如果已读到末尾,返回-1表示不能继续读取了。
FileInputStream
是InputStream
的一个子类。顾名思义,FileInputStream就是从文件流中读取数据。
public static void main(String[] args) throws IOException {
File f = new File("C:\\Users\\leevmh\\Desktop\\lee.txt");
String s;
int n;
try (InputStream input = new FileInputStream(f.getAbsolutePath())){
StringBuilder sb = new StringBuilder();
while ((n=input.read()) != -1){
sb.append( (char)n );
}
s =sb.toString();
}
System.out.println(s);
}
Java 7引入的新的try(resource)的语法,让编译器自动为我们关闭资源。
编译器并不会特别地为InputStream加上自动关闭。编译器只看try(resource = …)中的对象是否实现了java.lang.AutoCloseable接口,如果实现了,就自动加上finally语句并调用close()方法。
附加:代码案例
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
public class TxtFileRead {
public static void main(String[] args) {
readFile1();
System.out.println("===================");
//readFile2(); //JDK 7及以上才可以使用
}
public static void readFile1() {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
fis = new FileInputStream("c:/temp/abc.txt"); // 节点类,负责读字节
isr = new InputStreamReader(fis, "UTF-8"); // 转化类,将字节转化为字符
//isr = new InputStreamReader(fis);
br = new BufferedReader(isr); // 装饰类,负责从缓冲区读入字符
// br = new BufferedReader(new InputStreamReader(new
// FileInputStream("c:/temp/abc.txt")))
String line;
while ((line = br.readLine()) != null) // 每次读取一行
{
System.out.println(line);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
br.close(); // 关闭最后一个类,会将所有的底层流都关闭
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
//推荐使用try-resource来代替上面使用final的。
public static void readFile2() {
String line;
//try-resource 语句,自动关闭资源
try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("c:/temp/abc.txt")))) {
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
缓冲
在读取流的时候,一次读取一个字节并不是最高效的方法。
InputStream
提供了两个重载方法来支持读取多个字节:
int read(byte[] b)
读取若干字节并填充到byte[]数组,返回读取的字节数。
int read(byte[] b, int off, int len)
指定byte[]数组的偏移量和最大填充数。
public void readFile() throws IOException {
try (InputStream input = new FileInputStream("src/readme.txt")) {
// 定义1000个字节大小的缓冲区:
byte[] buffer = new byte[1000];
int n;
while ((n = input.read(buffer)) != -1) { // 读取到缓冲区
System.out.println("read " + n + " bytes.");
}
}
}
OutPutStream
OutputStream
也是抽象类,它是所有输出流的超类。
OutputStream
最重要的方法就是void write(int b)。虽然传入的是int参数,但只会写入一个字节,即只写入int最低8位表示字节的部分(相当于b & 0xff)。
每次写入一个字节非常麻烦,更常见的方法是一次性写入若干字节。这时,可以用OutputStream
提供的重载方法void write(byte[])
来实现:
public static void main(String[] args) throws IOException{
File f = new File("C:\\Users\\leevmh\\Desktop\\lee.txt");
try (OutputStream output = new FileOutputStream(f.getAbsolutePath())) {
output.write("Leevmh.".getBytes("UTF-8")); // Hello
}
}
OutputStream
还提供了一个flush()
方法,它的目的是将缓冲区的内容真正输出到目的地。
为什么要有flush()?因为向磁盘、网络写入数据的时候,出于效率的考虑,操作系统并不是输出一个字节就立刻写入到文件或者发送到网络,而是把输出的字节先放到内存的一个缓冲区里(本质上就是一个byte[]数组),等到缓冲区写满了,再一次性写入文件或者网络。对于很多IO设备来说,一次写一个字节和一次写1000个字节,花费的时间几乎是完全一样的,所以OutputStream有个flush()方法,能强制把缓冲区内容输出。
通常情况下,我们不需要调用这个flush()方法,因为缓冲区写满了OutputStream会自动调用它,并且,在调用close()方法关闭OutputStream之前,也会自动调用flush()方法。
附加:代码案例
import java.io.*;
public class TxtFileWrite {
public static void main(String[] args) {
writeFile1();
System.out.println("===================");
//writeFile2(); // JDK 7及以上才可以使用
}
public static void writeFile1() {
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream("c:/temp/abc.txt"); // 节点类,负责写字节
osw = new OutputStreamWriter(fos, "UTF-8"); // 转化类,将字符转化为字节
//osw = new OutputStreamWriter(fos); // 转化类
bw = new BufferedWriter(osw); // 装饰类,将字符写到缓冲区
// br = new BufferedWriter(new OutputStreamWriter(new
// FileOutputStream("c:/temp/abc.txt")))
bw.write("我们是"); //写数据
bw.newLine(); //换行
bw.write("Ecnuers.^^");
bw.newLine();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
bw.close(); // 关闭最后一个类,会将所有的底层流都关闭
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void writeFile2() {
//try-resource 语句,自动关闭资源
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:/temp/abc.txt")))) {
bw.write("我们是");
bw.newLine();
bw.write("Ecnuers.^^");
bw.newLine();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}