Java中每一种流的基本功能都依赖于它们。InputStream用于read,
OutputStream用于write。read和write都是相对于内存而言的,每个程序被
分配了内存空间,read就是从其他地方把数据拿进内存,提供给程序使用,write就是把数据从内存推出去。这两个都是抽象类,不能直接使用。 简单介绍InputStream和OutputStream的常用方法
InputStream: int read()
返回下一个数据字节,如果到达流的末尾,则返回 -1。
int read(byte[] b)
从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中,返回读入缓冲区的总字节数,如果到达流末尾而不再有数据,则返回 -1。
int read(byte[],int off,int len)
从InputStream中读取len个字节放入字节数组b下标为off到off+len的位置。返回读入缓冲区数组的总字节数,如果到达流末尾而不再有数据,则返回 -1。
long skip(long n)
跳过InputStream中n个字节。返回实际跳过的字节数。
void mark(int readlimit)
在流中标记当前位置。参数readlimit用来表示在标记位置失效之前可以从
InputStream流中读取的最大字节数。 void reset()
返回标记过的位置。
void close()
关闭流。
OutPutStream与InputStream类似: void write(int b)
写一个字节b到流中。
void write(byte[] b)
将数组中的内容写到流中。
void write(byte[] b,int off,int len)
将数组中从下标off指定的位置开始的len长度的数据写到流中。
void flush()
将缓冲区中的数据强制输出。
void close()
关闭流。
FileInputStream和FileOutputStream: FileInputStream用来对文件进行read操作,常用的方法已在其父类InputStream中定义。
FileOutputStream用来对文件进行write操作,常用的方法已在其父类OutputStream中定义。
import java.io.*;
publicclass FileStreamDemo {
publicstaticvoid main(String[] args) throws IOException {
// 创建两个文件,face.gif是已经存在文件,newFace.gif是新创建的文件
File inFile = new File(\"face.gif\");
File outFile = new File(\"newFace.gif\");
// 创建流文件读入与写出类
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile); }
}
// 通过available方法取得流的最大字符数
byte[] inOutb = newbyte[inStream.available()]; inStream.read(inOutb); // 读入流,保存在byte数组
outStream.write(inOutb); // 写出流,保存在文件newFace.gif中 inStream.close(); outStream.close();
ObjectInputStream和ObjectOutputStream: 用来对Object进行read和write。对象流是在普通流上加了传输对象的功能,所以构造对象流时要先构造普通文件流。
ObjectInputStream: final ObjectreadObject()
读入一个对象。返回的对象是Object类型的,强制类型转化到特定类型后才能使用。见代码。
ObjectOutputStream:
final void writeObject(Object obj)
把obj对象写入目的地。写入的具体内容由系统指定(一般看不懂)。
package TestObjectStream; import java.io.Serializable;
publicclassDogimplements Serializable { String name; intage;
String owner;
Dog(String name, int age, String owner) { this.name = name; this.age = age;
this.owner = owner; } }
package TestObjectStream;
/*把Dog类型的对象写入MyDog文件 *然后读出这个对象,强制类型转化成Dog。 *然后输出Dog的各项属性。 */
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectOutputStream;
publicclass Test {
publicstaticvoid main(String args[]) throws IOException,ClassNotFoundException{
FileOutputStream fos = new FileOutputStream(\"MyDog\"); ObjectOutputStream oos = new ObjectOutputStream(fos);
Dog myDog = new Dog(\"cute\", 1, \"z-please\"); oos.writeObject(myDog);
FileInputStream fis = new FileInputStream(\"MyDog\"); ObjectInputStream ois = new ObjectInputStream(fis);
Dog myLittleDog = (Dog)(ois.readObject()); System.out.println(myDog);
System.out.println(\"Name: \" + myDog.name); System.out.println(\"Age: \" + myDog.age);
System.out.println(\"Owner: \" + myDog.owner);
oos.close();
ois.close(); } }
DataInputStream和DataOutputStream: DataInputStream提供了readBoolean(),readInt()等原始基本数据类
型的方法。DataOutputStream正好相反。他们是在普通流上加了读写原始型数据的功能,所以构造他们时要先构造普通流。
package TestDataStream;
import java.io.DataInputStream; import java.io.DataOutputStream; importjava.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
publicclass Test {
publicstaticvoid main(String args[]) throws FileNotFoundException, IOException {
String name = \"cute\"; intage = 1;
FileOutputStream fos = new FileOutputStream(\"DogInfo\");
DataOutputStream dos = newDataOutputStream(fos); dos.writeChars(name); dos.writeInt(1);
FileInputStream fis = newFileInputStream(\"DogInfo\"); DataInputStream dis = new DataInputStream(fis); for (int i = 0; i < name.length(); i++) System.out.print(dis.readChar()); System.out.println();
System.out.println(dis.readInt());
dos.close(); dis.close(); } }
BufferedInputStream和BufferedOutputStream: FileInputStream和FileOutputStream对数据流的每次操作都是以字节为单位
进行的,既可以向输出流写入一个字节,也可从输入流中读取一个字节。显然效率太低,通常使用缓冲流,即为一个流配置一个缓冲区,一个缓冲区就是专门传送数据的一块内存。 他们是在普通文件流上加了缓冲的功能,所以构造他们时要先构造普通流。
package TestBufferedStream;
import java.io.*;
publicclass Test {
publicstaticvoid main(String args[]) throws FileNotFoundException,
IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
\"DogInfo\"));
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(\"DogInfoCopy\"));
//读取的字节数据先放在缓冲区,待缓冲区满了,才写入DogInfoCopy文件
} 字符流 }
int temp = bis.read(); while (temp != -1) { bos.write(temp); temp = bis.read(); }
bis.close(); bos.close();
BufferedReader FileReader Reader InputStreamReader BufferedWriter Writer OutputStreamWriter FileWriter 上面的几种流的单位是byte,所以叫做字节流,写入文件的都是二进制字节,我们无法直接看,下面要学习的是字符流。 字符流分两类:Reader和Writer
以字符为单位读取文件,常用于读文本,数字等类型的文件。
Reader和Writer类定义的方法与InputStream和OutputStream类的方法类似。
Java采用Unicode字符集,每个字符和汉字都采用2个字节进行编码,ASCII码是Unicode编码的子集InputStreamReader是字节流到字符桥的桥梁
(byte->char读取字节然后用特定字符集编码成字符)。
OutputStreamWriter是字符流到字节流的桥梁(char->byte)。
他们是在字节流的基础上加了桥梁作用,所以构造他们时要先构造普通文件流。
package TestStreamReaderWriter;
import java.io.*; /*
* DogInfo文件里的内容:你好
* 使用字节流读出:???? * 使用字符流读出:你好
* */
publicclass Test {
publicstaticvoid main(String args[]) throws FileNotFoundException, IOException {
//使用字节流读出文件内容
FileInputStream fis = new FileInputStream(\"DogInfo\"); DataInputStream dis = new DataInputStream(fis); int temp;
while ((temp = dis.read())!=-1) System.out.print((char)temp);
}
}
dis.close();
//使用字符流读出文件内容
FileInputStream fis2 = new FileInputStream(\"DogInfo\"); InputStreamReader isr = new InputStreamReader(fis2); System.out.println();
while ((temp = isr.read())!=-1) System.out.print((char)temp);
isr.close();
FileReader和FileWriter: FileReader:
该类没有特有的方法,只有自己的构造数,常用于处理文本文件。
FileReader(String filename)
构造函数:在读取流对象初始化的时候,必须要指定一个被读取的文件。如果该文件不存在会发生FileNotFoundException。 FileWriter:
FileWriter(Stringfilename)
构造函数:调用系统资源,在指定位置,创建一个文件。注意:如果该文件已存在,将会被覆盖。
import java.io.*;
publicclass Test {
publicstaticvoid main(String[] args) throws IOException { }
}
// 创建两个文件,Dog.txt是已经存在文件,DogCopy.txt是新创建的文件
File inFile = new File(\"Dog.txt\");
File outFile = new File(\"DogCopy.txt\");
// 创建流文件读入与写出类
FileReader fr = new FileReader(inFile); FileWriter fw = new FileWriter(outFile); int temp;
while((temp = fr.read())!= -1){
fw.write(temp); // 写出流,保存在文件DogCopy.txt中
}
fr.close(); fw.close();
BufferedReader和BufferedWriter: 他们是在普通文件流上加了缓冲的功能,所以构造他们时要先构造FileReader或者
FileWriter。 BufferedReader: StringreadLine() 读取一行。
package TestBufferedReaderWriter;
import java.io.*;
publicclass Test {
publicstaticvoid main(String args[]) throws FileNotFoundException, IOException {
FileWriter fw = new FileWriter(\"DestFile\"); BufferedWriter bw = new BufferedWriter(fw);
//先把字节数据写入缓冲区,待缓冲区满了,再写入DestFile文件。
//这能提高效率,虽然在数据量不大的情况下不一定看得出来。
}
}
for(int i = 0; i < 10000; i++){ bw.append('A'); }
bw.flush(); bw.close();
总结: 这部分的难点就是类比较复杂,尤其是每个类的构造方式,我认为记住下面这个图比记类的继承关系更好些。 a.字节流:
InputStream
1.FileInputStream(基本文件流) 2.BufferedInputStream 3.DataInputStream
4.ObjectInputStream
OutputStream同上图
BufferedInputStream,DataInputStream,ObjectInputStream只是在FileInputStream上增添了相应的功能,构造时先构造FileInputStream。
b.字符流:
Reader:
1.InputStreamReader (byte->char 桥梁) 2. BufferedReader(常用) Writer:
1.OutputStreamWriter (char->byte桥梁) 2. BufferedWriter
提醒:整理这个文档是为了加深对Java文件流的理解,所以只介绍了我认为重要的一部分
类与方法。 参考资料:
http://www.05sun.com/article/article_7078_4.html
http://www.cnblogs.com/jjtech/archive/2011/04/17/2019210.html
因篇幅问题不能全部显示,请点此查看更多更全内容