数据流:(package:java.io)
数据流分为输入流(inputStrean)和输出(outputStream)。输入流只能从中读取数据,而不能向其去写入数据。输出流只能向其写入数据,而不能从中读取数据。
1、字节流类InputStream和OutputStream是两个抽象类,InputStream包括了字节输入流的所有方法,OutputStream包括了字符输出流的所有方法。
字节输入流
--------------------------------------------------------------------------------------------------
流 | 描述
--------------------------------------------------------------------------------------------------
FileInputStream | 文件字节输入流
ByteArrayInputStream | 字节数组输入流
PipedInputStream | 管道输入流
BufferedInputStream | 缓冲输入流
FilterInputStream | 过滤字节输入流
ObjectInputStream | 对象输入流
DataInputStream | 包含读取java标准数据类型方法的输入流
--------------------------------------------------------------------------------------------------
输出字节流
--------------------------------------------------------------------------------------
流 | 描述
--------------------------------------------------------------------------------------------------
FileOutputStream | 文件字节输出流
ByteArrayOutputStream | 字节数组输出流
PipedOutputStream | 管道输出流
BufferedOutPutStream | 缓冲输出流
FilterOutputStream | 过滤字节输出流
ObjectOutputStream | 对象输出流
DataOutputStream | 包含读取java标准数据类型方法的输出流
PrintStream | 包含print()和println()的输出流
--------------------------------------------------------------------------------------------------
1.1 通过字节流读写数据
InputStream 是字节输入流的超类,描述了所有字节输入的方法。下面是InputStream的主要方法。
(1)、int read();从输入流中读取下一个字节,并以int类型返回。返回值的去取值范围为0~255,若
遇到输入流的末尾则返回-1.该方法的属性是abstract,因此必须在子类中实现。下面这两个 方法是read()方法的重写。
-> int read(byte b[]):从输入流中读取长度为b.length的字节到b中,并返回本次读取的字 节数。如果遇到输流的末尾则返回-1.
-> int read(byte b[],int off,int len):从输入流中读取长度为len的字节,写入b中
从下标off开始的位置,并返回本次读取的字节数。
(2)、void close();关闭但前的输入流,同时释放相关的系统资源。
(3)、int available();返回当前输入流中可读取的字节数。
(4)、long skip(long n);跳过n个字节,返回实际跳过的字节数。
(5)、void mark(int readlimit);在输入流的当前位置设置标记,该标记再从流中读取readlimit个 字节前都保持有效。
(6)、boolean markSupported();测试调用的流是否支持mark()/reset(),如果支持则返回true.
上述方法在调用时如果出现错误,则这些方法将抛出一个IOException异常。
OutputStream是字节输出流的超类,描述了所有字节输出的方法。下面是inputStream的主要方法:
(1)、void write(int b);将指定的字节b作为数据写入输出流。该方法的属性是abstract,因此必须 在子类中实现。下面这两个方法是write()方法法的重写:
-> void write(byte[] b);将字节数组b中长度为b.length个字节的数据写入输出流。
-> void write(byte[] b,int off,int len);将字节数组b中从下标off开始的长度为len个字 节的数据写入输出流。
(2)、flush();刷新输出流。
(3)、close();关闭当前的输出流,同时释放相关的系统资源。
1.2 FileInputStream 类
FileInputStream类继承了InputStream类。它重写了父类中所有的方法。FileInputStream类用于进行文件的输入处理,其数据源和接受文件都是文件。
FileInputStream类的两个常用构造函数:
FileInputStream(String filepath)和FileInputStream(File fileObj).
如果构造函数中的参数filepath或fileObj不存在,将会生成一个FileNotFoundException,这是一个非运行时异常,必须捕获或声明抛出,否则编译会出错。
FileInputStream重写了父类InputStream中的发放那个发read()、close()、skip()、和available(),不支持方法mark()/reset()。
1.3 FileOutputStream 类
FileOutputStream 类的构造函数和FileInputStream类的构造函数不同,它的构造函数有3种形式。其构造函数的形式如下:
FileOutputStream(String filepath)
FileOutputStream(File fileObj)
FileOutputStream(String filepath,Boolean append)
其中,filepath是指被打开并且血药写入数据的文件名。fileObj是指被打开并且需要写入数据的文件。参数append为true,文件以追加方式打开,不覆盖已有的文件内容;如果为false,则覆盖源文件的内容。
FileOutputStream对象的创建不依赖文件是否存在。如果文件不存在,FileOutputStream 会在打开输入出文件前创建它。如果文件已经存在,则打开它,准备写入内容。如果FileOutputStream试图打开一个只读的文件,会引发一个IOException异常。
以下为一个简单的文件复制实例:
import java.io.*;
class ExampleFileOutputStream{
public static void main(String args[]){
int i;
try{
//创建了类FileInputStream的一个对象
FileInputStream fis = new FileInputStream("text.txt");
//创建类FileOutputStream的一个对象
FileOutputStream fos = new FileOutputStream("texttest.txt");
i = fis.read();
while(i!=-1){
fos.write(i);
i = fis.read();
}
fis.close();
fos.close();
}catch(IOException e){
System.out.println("打开文件时发生错误");
}
}
}
1.4 DataInputStream 类和DataOutputStream 类
在前面的学习中,我们知道数据流处理的数据都是指字节或字节数组,但实际上很多时候不是这样的,它需要数据流能直接读、写各种各样的java语言的基本数据类型。例如在一个文件中存放300个整数值,从中读取时,希望按int为基本单位进行读取,这样可以大大节省时间。这时就需要使用DataInputStream和DataOutputStream,DataInputStream和DataOutputStream不但支持父类InputStream和OutputStream中的方法,以原有方式读写数据,同时还允许通过数据流来读写java语言的基本数据类型,包括int、float、double和double等。其构造函数形式如下:
DataInputStream(Obj)
DataOutputStream(Obj) Obj为已经建立好的输入输出数据流对象
DatainputStream 和 DataOutputStream之所以能够对这些原始类型进行操作,是因为他们有一组特定的方法。DataInputStream 的常用方法如下:
-> byte readByte()
-> long readLong()
-> double readDouble()
-> boolean readBoolean()
-> String readUTF()
-> int readInt()
-> float readFloat()
-> short readShort()
-> char readChar()
以上这些方法分别对int、byte、float、char等类型进行读取。
-> void writeByte(int a)
-> void writeLong(long a)
-> void wirteDouble(double a)
-> void writeBoolean(boolean a)
-> void writeUTF(String a)
-> void writeInt(int a)
-> void writeChar(char a)
-> void writeFloat(float a)
-> void writeShort(short a)
以上这些方法分别对int、byte、float、char等类型进行写入。
以下是关于DataInputStream 和 DataOutputStream 实例:
import java.io.*;
public class Example{
public static void main(String args[]){
FileOutputStream fos = new FileOutputStream("text.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.write(12);
dos.write(2.23d);
dos.write(true);
dos.write("java 数据流测试#");
fos.close();
FileInputStream fis = new FileInputStream("text.txt");
DataInputStream dis = new FileInputStream(fis);
System.out.println(dis.readInt());
S ystem.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
char a;
while((a = dis.readChar())!=\'#\'){
System.out.println(a);
}
System.out.prinltn("n");
fis.close();
}
}
1.5 引入缓冲流读取文件
文件字节输入/输出流是以字节为单位进行读写操作的,这使得文件流的效率很低,这时就需要用到BufferedInputStream 类 BufferedOutputStream 类。当输入数据时,数据以块为单位读入缓冲区,此后如有读操作,则直接访问缓冲区。当输出数据时,数据不直接向输出流输出数据,而是将数据先写入缓冲区,当缓冲区中的数据写入输出流中,这样就提高了I/O操作的效率。
BufferedInputStream 和 BufferedOutputStream 还支持mark()、reset()、skip()等方法。
BufferedInputStream 是InputStream 的子类,称为缓冲输入流。BufferedOutputStream 是 OutputStream的子类,称为缓冲输出流。其常用的构造方式如下:
BufferedInputStream(Obj)
BufferedOutputStream(Obj)
其中,Obj为已经建立好的输入输出数据流对象。
以下为关于 BufferedInputStream 和 BufferedOutputStream 的实例:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class example(){
public static void main(String args[]){
FileInputStream fis;
FileOutputStream fos;
BufferedInputStream bis;
BufferedOutputStream bos;
int i;
try{
fis = new FileInputStream("text.txt");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("text.txt");
bos = new BufferedOutputStream(fos );
i = bis.read();
while(i != -1){
bos.write(i);
bos.flush();
i = bis.read();
}
fis.close();
fos.close();
bis.close();
bos.close();
}catch(IOException e){
System.out.println("打开文件时出错");
}
}
}
虽然字节流的功能十分强大,它能字节或间接的处理任何数据类型的输入和输出操作,但是却不能字节操作16位的Unicode字符。这时提供直接的字符输入和输出就显得非常有必要了。下面将着重介绍字符流。
2、字符流类Reader和Writer也是两个抽象类。由于java采用16位的Unicode字符编码,所以这些抽象类处理的是Unicode的字符流。
输入字符流
--------------------------------------------------------------------------------------------------
流 | 描述
--------------------------------------------------------------------------------------------------
FileReader | 文件字符输入流
CharArrayReader | 从字符数组读取的输入流
StringReader | 读取字符串的输入流
PipedReader | 管道字符输入流
BufferReader | 缓冲输入流
FilterReader | 过滤字符输入流
InputStreamReader | 将字节输入流转换为字符输入流
--------------------------------------------------------------------------------------------------
输出字符流
--------------------------------------------------------------------------------------------------
流 | 描述
--------------------------------------------------------------------------------------------------
FileWriter | 文件字符输出流
CharArrayWriter | 从字符串数组读取的输出流
StringWriter | 读取字符串的输出流
PipedWriter | 管道字符输出流
BufferedWriter | 缓冲输出流
FilterWriter | 过滤字符输出流
OutputStreamWriter | 将字节输出流转换为字符输出流
PrintWriter | 打印字符输出流
--------------------------------------------------------------------------------------------------
2.1如何读取Unicode字符
Reader 类 和Writer 类处在字符流的顶层,是所有字符流的基类。同时Reader和Writer类都是抽象的,它们仅提供了基本的函数类型,没有其具体的实现,所以不能直接生成对象。要通过其子类来生成所需对象,同时必须重写Reader和Writer类中的方法。类Reader是字符输入流的超类,描述了所有字符输入的方法。
下面是Reader的主要方法。
(1)、int read():从输入流中读取下一个字符,并以int类型返回。返回值的取值范围为0~65535,若遇到 输入流的末尾则返回-1.
-> int read(char[] buffer);从输入流中读取长度为buffer.length的字符到buffer中,并返回本 次读取的字符数。如果遇到输入流的末尾则返回-1.
-> abstract int read(char[] buffer,int off,int len);从输入流中读取长度为len的字符,写入 buffer中从下标off开始的位置,并返回本次读取的字符数。
(2)、void close();关闭当前的输入流,同时释放相关的系统资源。
(3)、long skip(long n);跳过n个字符,返回实际跳过的字符数。
(4)、 void mark(int readlimit);再输入流的当前位置设置标记,该标记再从流中读取readlimit个字符 前都保持有效
(5)、boolean markSupported();测试调用的流是否支持mark()/reset(),如果支持,则返回true.
(6)、 boolean ready();测试输入流是否准备好读取字符。
(7)、void reset();重置输入指针到先前设定的标记处。
类Writer是字符输出流的超类,描述了所有字符输出的方法。下面是Writer的主要方法。
(1)、void write(int c);将指定的字符c作为数据写入输出流。下面这个两个方法是对writer方法的重写。
-> void write(char[] buffer);将字符串数组中长度为buffer.length个字符的数据写入到输出 流中。
-> abstract void write(char[] buffer,int off,int len);将字符串数组buffer中从下标off开始 的长度为len个字符的数据写入输出流。
(2)、void write(String str);将字符串str写入输出流。
(3)、void write(String str,int off,int len);将字符串中以off为起点的len个字符写入输出流。
(4)、void close();关闭当前的输出流,同时释放相关的系统资源。
(5)、void flush(); 刷新输出流。
2.2 读取字符文件
FileReader类和FileWriter类分别集成饿了Reader和Writer类,它们重写了父类中所有的发法。它们主要用于字符文件的读写操作。FileReader类用于读取字符文件的内容,每次读取一个字符或一个字符数组。FileWriter用于写入字符文件的内容,每次写入一个字符或一个字符串。
FileReader类的两个常用构造函数如下所示;
FileReader(String filepath);
FileWriter(File fileObj);
其中,filepath是指被打开并被读取数据的文件的全称路径,fileObj是指被打开并被读取数据的文件。如果构造函数中的参数filepath或fileObj不存在,将生成一个FileNotFoundException,这是一个非运行时异常,必须捕获或声明抛出,否则编译错误。
FileWriter类常用的构造函数如下所示:
FileWriter(String filepath);
FileWriter(String filepath,boolean append);
FileWriter(File fileObj);
其中,filepath是指被打开并且需要写入数据的文件名,fileObj是指被打开并且需要写入数据的文件。参数为true,文件以追加的方式打开,不覆盖原有的文件内容;如果为false则会覆盖原有的文件内容。
FileWriter 对象的创建不依赖文件是否存在。
以下是关于FileReader和FileWriter的实例演示:
import java.io.*;
public class Example{
public static void main(String args[]){
int i;
FileReader fr;
FileWriter fw;
try{
fr = new FileReader("text.txt");
}catch(FileNotFoundException e){
System.out.println("没有发现需要打开的文件");
return ;
}
try{
fw = new FileWriter("text1.txt");
}catch(FileNotFoundException e){
System.out.println("error");
return ;
}
try{
i = fr.read();
while(i!=-1){
fw.write(i);
i = fr.read();
}
fr.close();
fw.close();
}catch(IOException e){
System.out.println("error");
}
}
}
2.3 BufferedReader 和 BufferedWriter 类
缓冲字符流BufferedReader 和 BufferedWriter 和缓冲字节流一样,引进缓冲字符流的目的也是为了提高I/O操作的效率。BufferedReader 和 BufferedWriter 类的常用构造方法如下:
BufferedReader(Obj);
BufferedWriter(Obj);
BufferedReader 和 BufferedWriter的方法与Reader和Writer类中的方法基本相同,同时还有新增的方法。String readLine()函数的功能的是读入字符,直到遇到“n”或"r"为止。
2.4 通过字符读取文件及写出
字节流的读取是以单个字节为单位的,而字符流的读取是以单个字符为单位的。一般字符是由多个字节组成。java语言内部可将一个字节流转化为字符流,这种转化是由InputStreamReader 和 OutputStreamWriter 来完成的。可以再生成InputStreamReader 和 OutputStreamWriter 类的对象时指定编码规范,也可以使用当前平台默认的编码规范。
InputStreamReader类的构造函数如下所示:
InputStreamReader(InputStream in)//使用当前平台的默认编码规范,将字节输入流in转换成一个 字符输入流
InputStreamReader(InputStream in,String charname);//使用指定的编码规范,将字节输入流in转换成一个字符输入流。如果编码规范错误,将抛出UnsupportedEncodingException异常。
OutputStreamWriter 类的构造函数如下;
OutputStreamWriter(OutputStream out);//使用当前平台的默认编码规范,将字节输出流out转换成一个字符输出流。
OutputStreamWriter(OutputStream out,String charname);//使用指定的编码规范,将字节输出流out转换成一个字符输出流。如果编码规范错误,将抛出UnsupportedEncodingException异常。
关于InputStreamReader 和 OutputStreamWriter 类的使用示例如下:
import java.io.*;
public class Example{
public static void main(String args[]){
try{
FileInputStream fis = new FileInputStream("text1.txt");
//将字节流转化为字符流文件
InputStreamReader isr = new InputStreamReader(fis);
//带缓冲的输入文件
BufferedReader br = new BufferedReader(isr);
FileOutputStream fos = new FileOutputStream("text2.txt");
//将字节流转化为字符流文件
OutputStreamWriter osw = new OutputStreamWriter(fos);
//带缓冲的输出文件
BufferedWriter bw = new BufferedWriter(osw);
String s;
while((s = br.readLine() != null){
bw.write(s);
bw.flush();//强制输出
}
fis.close();
isr.close();
br.close();
bw.close();
osw.close();
fos.close();
}catch(IOException e){
System.out.println(e);
}
}
}
相关文章: