您的当前位置:首页正文

Java流

2023-12-22 来源:我们爱旅游
Java文件流 在Java中把不同的数据源与程序之间的数据传输都抽象表述为“流”(stream),以实现相对统一和简单的输入/输出操作方式。传输中的数据就像流水一样,称为数据流。 按传输的数据类型分: 字节流 FileInputStream 字节流 OutputStream 表示继承 FilterOutputStream BufferedOutputStream ObjectOutputStream DataOutputStream InputStream ObjectInputStream DataInputStream FilterInputStream BufferedInputStream 数据流 字符流 FileOutputStream 字节流分两类:InputStream和OutputStream。 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。

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

因篇幅问题不能全部显示,请点此查看更多更全内容