一个流是一个有序的字节序列。当进行输入(读) 或输出(写)数据操作时,数据从信息源流向目的地就像水在水管里流淌一样。给水管注入水的一端就是信息源,水流出的一端就是目的地。流既可以作为输入源,也可以作为输出的目的地。流中的字节具有严格的顺序,按先进先出的要求操作,因此流式I/O是一种顺序存取方式。
java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能,可以从不同角度对其分类:
---按数据流的方向不同可以分为输入流和输出流
---按处理数据单位不同可以分为字节流和字符流
---按照功能不同可以分为节点流和处理流
JDK提供的所有流类型位于包java.io内都分别继承自以下四种抽象流类型:
字节流 | 字符流 | |
输入流 | InoutStream | Reader |
输出流 | OutputStream | Writer |
节点流为可以从一个特定的数据源(节点)读写数据(如:文件、内存)
处理流是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更强大的读写功能
继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit)
继承自OutputStream的流都是用于向程序中输出数据,且数据的单位为字节(8bit)
继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit)
继承自writer的流都是用于向程序中输出数据,且数据的单位为字符(16bit)
程序如下:
import java.io.*;
public class TestFileInputStream {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
try {
in = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java");
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
System.exit(-1);
}
try {
long num = 0;
while((b=in.read())!=-1){
System.out.print((char)b);
num++;
}
in.close();
System.out.println();
System.out.println("共读取了 "+num+" 个字节");
} catch (IOException e1) {
System.out.println("文件读取错误"); System.exit(-1);
}
}
}
import java.io.*;
public class TestFileOutputStream {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("d:/share/java/HelloWorld.java");
out = new FileOutputStream("d:/share/java/io/HW.java");
while((b=in.read())!=-1){
out.write(b);
}
in.close();
out.close();
} catch (FileNotFoundException e2) {
System.out.println("找不到指定文件"); System.exit(-1);
} catch (IOException e1) {
System.out.println("文件复制错误"); System.exit(-1);
}
System.out.println("文件已复制");
}
}
import java.io.*;
public class TestFileReader {
public static void main(String[] args) {
FileReader fr = null;
int c = 0;
try {
fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java");
int ln = 0;
while ((c = fr.read()) != -1) {
//char ch = (char) fr.read();
System.out.print((char)c);
//if (++ln >= 100) { System.out.println(); ln = 0;}
}
fr.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
} catch (IOException e) {
System.out.println("文件读取错误");
}
}
}
import java.io.*;
public class TestFileWriter {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("d:\\bak\\unicode.dat");
for(int c=0;c<=50000;c++){
fw.write(c);
}
fw.close();
} catch (IOException e1) {
e1.printStackTrace();
System.out.println("文件写入错误");
System.exit(-1);
}
}
}
缓冲流
缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
---缓冲输入流支持其父类的mark和reset方法
---BufferedReader提供了readLine方法用于读取一行字符串
转换流
InputStreamReader和OutputStreamWriter用于字节数据到字符数据间的转换
InputStreamReader要和InoutStream"套接”
OutputStream要和OutputStream"套接”
转换流在构造时可以指定其编码集合,例如:
InputStream is = new InputStreamReader
(System.in,"ISO8859_1")
数据流
DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,它们属于处理流,需要分别“套接”在InoutStream和OutputStream类型的节点流之上
Print流
PrintWriter和PrintStream都属于输出流,分别针对于字符和字节
PrintWriter和PrintStream提供了重载的print方法
println方法用于多种数据类型的输出
printWriter和printStream有自动的flush功能
Object流
直接将Object读入或写出