一、流的概述
流是一组有序的数据序列,根据操作的类型,可以分为输入流和输出流。I/O流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。二、输入模式 输出模式图
三、java流的分类
按流向分:
输入流: 程序可以从中读取数据的流。
输出流: 程序能向其中写入数据的流。
按数据传输单位分:
字节流: 以字节为单位传输数据的流
字符流: 以字符为单位传输数据的流按功能分:
节点流: 用于直接操作目标设备的流处理流: 是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。
四、字节输入流(InputStream)/字节输出流(OutputStream)简介及方法
InputStream类是字节输入流的抽象类,是所有字节输入流的父类。必须依靠其子类实现各种功能,且数据单位为字节(8bit);他是指数据以字节形式从其他文件或者设备向程序流入。常用方法如下:
(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
(2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返 回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.
OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类;他是数据以字节形式从程序流出,输出流只能向流中写入数据
OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
1. public void write(byte b[ ]):将参数b中的字节写到输出流。
2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
注意:并不是所有的inputstream类的子类都支持inputstream中定义的方法,如skip() mark() reset()等方法只对某些子类有用
五、文件输入/输出流实例
FileInputStream类与FileOutputStream类
<span style="font-size:12px;">/*文件输入流: FileInputStream类
作用:以文件作为数据输入源的数据流。或者说是打开文件,从文件读数据到内存的类。
*/
import java.io.IOException;
import java.io.FileInputStream;
;
public class TestFile {
public static void main(String args[]) throws IOException {
try{
FileInputStream rf=new FileInputStream("A.java"); //有内容的java文件
int n=512; byte b[]=new byte[n];
while((rf.read(b,0,n)!=-1)&&(n>0)){
System.out.println(new String(b) );
}
System.out.println();
rf.close();
} catch(IOException IOe){
System.out.println(IOe.toString());
}
}
}
/*文件输出流:FileOutputStream类
作用:用来处理以文件作为数据输出目的数据流;或者说是从内存区读数据入文件
*/
import java.io.IOException;
import java.io.FileOutputStream;
public class TestFile {
public static void main(String args[]) throws IOException {
try {
System.out.println("请输入");
int count, n = 512;
byte buffer[] = new byte[n];
count = System.in.read(buffer); //从键盘接收
FileOutputStream wf = new FileOutputStream("d:/write.txt"); //文件需要已存在
wf.write(buffer, 0, count);
wf.close(); // 当流写操作结束时,调用close方法关闭流。
System.out.println("内容保存成功!");
} catch (IOException IOe) {
System.out.println("文件写入失败!");
}
}
}</span>
Reader用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
1) FileReader :与FileInputStream对应
主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:
(1)将文件名作为字符串 :FileReader f=new FileReader(“c:/temp.txt”);
(2)构造函数将File对象作为其参数。
File f=new file(“c:/temp.txt”);
FileReader f1=new FileReader(f);
(3) 构造函数将FileDescriptor对象作为参数
FileDescriptor() fd=new FileDescriptor()
FileReader f2=new FileReader(fd);
主要方法
(1) 用指定字符数组作为参数:CharArrayReader(char[])
(2) 将字符数组作为输入流:CharArrayReader(char[], int, int)
读取字符串,构造函数如下: public StringReader(String s);
(3) CharArrayReader:与ByteArrayInputStream对应
(4) StringReader : 与StringBufferInputStream对应
(5) InputStreamReader从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is);
(6) FilterReader: 允许过滤字符流 protected filterReader(Reader r);
(7) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。 Public BufferReader(Reader r);
Writer 写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。
1) FileWrite: 与FileOutputStream对应
将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。
Public FileWrite(file f);
2) chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。
Public CharArrayWrite();
3) PrintWrite:生成格式化输出
public PrintWriter(outputstream os);
4) filterWriter:用于写入过滤字符流
protected FilterWriter(Writer w);
5) PipedWriter:与PipedOutputStream对应
6) StringWriter:无与之对应的以字节为导向的stream
主要方法:
(1) public void write(int c) throws IOException; //将整型值c的低16位写入输出流
(2) public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流
(3) public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
(4) public void write(String str) throws IOException; //将字符串str中的字符写入输出流
(5) public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流
(6) flush( ) //刷空输出流,并输出所有被缓存的字节。
(7) close() 关闭流 public abstract void close() throws IOException
----------------------------------------------------------------------------------------------------------------------------
字节与字符的转换流
说到这先说一下二者的区别
1)字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,
2)而字节流处理单元为1个字节, 操作字节和字节数组。
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!
如果是 音频文件、图片、歌曲,就用字节流好点。
如果是关系到中文(文本)的,用字符流好点
InputStreamReader 和OutputStreamWriter 分别是Reander和Writer的子类,二者用于字节流和字符流之间的转换。
InputStreamReader用于将输入的字节流转变为字符流
OutputStreamWriter 用于将输入的字符流转变为字节流
Reader reader = new InputStreamReader(new FileInputStream("d:\\1.txt"));
System.out.println(reader.read());
reader.close();
File f=new File(“d:/1.txt”);
OutputStreamWriter os=new OutputStreamWriter(new FileOPutInStream(f));
Os.write(“hello word”);
Os.close();
---------------------------------------------------------------------------------------------------------------
七、带缓存的输入/输出流
BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。
BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。
1)将文件读入内存:
将BufferedInputStream与FileInputStream相接
FileInputStream in=new FileInputStream( “file1.txt ” );
BufferedInputStream bin=new BufferedInputStream( in);
2)将内存写入文件:
将BufferedOutputStream与 FileOutputStream相接
FileOutputStreamout=new FileOutputStream(“file1.txt”);
BufferedOutputStream bin=new BufferedInputStream(out);
BufferedReader和BufferedWriter是带缓冲区的Reader和Writer.
使用BufferedReader读取文本时,将首先从文件中读取字符数据并存入缓冲区中,然后调用read(),先冲缓冲区开始读取,缓冲区不足是再从文件中读取;
使用BufferedWriter时,写入数据将先存储到缓冲区中,在缓冲区饱满的情况下将一次性写入目的地。
通过缓冲区可以减少对硬盘的输入或输出操作,提高文件存取效率。
File f=new File(“d;/demo.txt);
FileWriter bufWriter=new BufferedWriter(writer);
bufWriter.writer(“hello word);
bufwruter.close();
writer.close();
FileReader reader =new FileReader(“f);
BufferedReader bufReader=new BufferedReader(reader);
Sysout.out.print(bufReader.readLine());
八、数据输入/输出流
DataInputStream与DataOutputStream允许应用程序以与机器无关的方式从底层输入流中读取基本java数据类型。
简单说就是,当读取一个数据时,不必再关心这个数值应当是哪种字节
构造方法
DataInputStream(InputStream in) 使用指定的底层 InputStream 创建一个 DataInputStream
DataOutputStream(OutputStream out) 创建一个新的数据输出流,将数据写入指定基础输出流。
DataOutputStream类提供的3种写入方法
writeBytes(String s) 将字符串按字节顺序写出到基础输出流中。
writeChars(String s) 将字符串按字符顺序写入基础输出流。
writeUTF(String str) 以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。
<span style="font-size:12px;">public static void main(String[] args) throws Exception {
//创建FileOutputStream对象
FileOutputStream fos=new FileOutputStream("d:/1.txt");
//创建DataOutputStream对象
DataOutputStream dos=new DataOutputStream(fos);
//写入磁盘文件数据
dos.writeUTF("使用writeUTF()方法写入数据");
// dos.writeBytes("使用writeBytes()方法写入数据");
// dos.writeChars("使用writeChars()方法写入数据");
dos.close();//关闭流
//创建FileInputStream对象
FileInputStream fis=new FileInputStream("d:/1.txt");
//创建DataInputStream对象
DataInputStream dis=new DataInputStream(fis);
System.out.print(dis.readUTF()); //将文件输入输出
}
}</span>
九、一言不合就上题:文件及文件夹的拷贝实例
<span style="font-size:12px;">public static void main(String[] args) {
File f=new File("d:/英雄时刻");
new File(f, f.getName()).mkdir();
copyDirectory(new File("d:/英雄时刻"),new File( "e:/"));
try {
copyFile(new File("d:/1.txt"), new File("e:/1.txt"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("拷贝完毕!");
}
//文件的复制
public static void copyFile(File f1,File f2) throws IOException{
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(f1));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(f2));
byte [] b=new byte[512];
int len;
while((len=bis.read(b))!=-1){
bos.write(b, 0, len);
}
bos.flush();
if(bos!=null)
bos.close();
if(bos!=null)
bis.close();
}
//文件夹的复制
public static void copyDirectory(File f1,File f2){
File f=new File(f2, f1.getName());
f.mkdir();
File []fl=f1.listFiles();
for (File file : fl) {
if(file.isDirectory()){
copyDirectory(file, f);
}
else{
try {
copyFile(file, new File(f,file.getName()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}</span>
十、IOException异常类的子类
1.public class EOFException :
非正常到达文件尾或输入流尾时,抛出这种类型的异常。
2.public class FileNotFoundException:
当文件找不到时,抛出的异常。
3.public class InterruptedIOException:
当I/O操作被中断时,抛出这种类型的异常。
为什么要有异常处理
因为在输入输出中,会出现一些你想不到的异常,所以要用try catch语句捕获这些异常并做友好提示,方便我们的操作
比如读文件时你的文件不存在 它会出现系统错误,为了方便,捕获他做友好提示很方便继续操作
更多内容:
http://blog.csdn.net/hguisu/article/details/7418161
http://blog.csdn.net/xfhuajian/article/details/6439374