-------android培训、java培训、期待与您交流! ----------
IO流
什么是流:
流就是程序和设备之间嫁接起来的一根用于数据传输的管道,这个管道上有很多按钮,不同的按钮可以实现不同的功能
节点流与处理流:
节点流:(也叫原始流)
节点流为可以从一个特定的数据源(节点)读写数据(如:文件,内存)
处理流:(也叫包裹流)
处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能
流的分类和使用:
四大基本抽象流:
InputStream和OutputStream读写数据的单位是一个字节,Reader和Writer读写数据的单位的一个字符
InputStream OutputStream Reader Writer 这四个类都是抽象类
凡是以Stream结尾的都是字节流
InputStream 流中常用的方法:
public int read() 读取一个字节并以整数的形式返回,如果读取到输入流的末尾则返回-1
public int read(byte[] b)从输入流中读取一定数据的字节,并将其存储在缓冲区数组b中,以整数形式返回实际的字节数
public int read(byte[] b, int off, int len) 从输入流中最多读取len个字节的数据并存入bete中
public void close() 关闭此输入流并释放与该流关联的所有系统资源
OuputStream 流中的常用方法:
public void write(int b) 向输入流中写入一个字节数据,该字节数据为参数b的低8位
public void write(byte[] b) 将一个字节类型的数组中的数据写入输出流
public void wirte(byte[] b, int off, int len) 将一个字节类型的数组中的从指定位置(off)开始的len个字节定稿到输出流
public void close() 关闭流释放内存资源
public void flush() 将输出流中缓冲的数据全部写出到目的地
Reader 流中的常用方法:
public int read() 读取一个字符并以整数的形式返回(0~255),如果返回-1已到输入流的末尾
public int read(char[] cbuf) 读取一系列字符并存储到一个数组buf,返回实际读取的字符数,台电读取前已到输入流的末尾返回-1
public int read(char[] cbuf, int offset, int length) 最多读取length个字符,并存储在一个数组buf,从length位置开始,返回实际读取的字符数,如果读取前已到输入流末尾返回-1
public void close() 关闭流释放内存资源
public long skip(long n) 跳过 n 个字符不读,返回实际跳过的字节数
Writer 流中的常用方法:
public void write(int c) 向输出流中写入一个字符数据,该字符数据为参数b的低16位
public void write(char[] buf) 将一个字符类型的数组中的数据写入输出流
public void write(char[] buf, int offset, int length) 将一个字符类型的数组中的从指定位置(offset)开始的length个字符写入到输出流
public void write(String str) 将一个字符串的字符写入到输出流
public void write(String str, int offset, int length) 将一个字符串从offset开始的length个字符写入到输出流
public void close() 关闭流释放内存资源
public void flush() 将输出流中的缓冲的数据全部写出到那目的地
字节流与字符流的区别:
FileInputStream 和 FileOutputSteram 可以完成所有格式文件的复制
FileReader 和FileWirte 只可以完成文本文件的复制,却无法完成视频格式文件的复制
因为字节是不需要解码和编码的,将字节转化为字符才存在解解码和编码的问题
字节流可以从所有的格式的设备中读写数据,但字符流只能从文本格式的设备中读写数据
文件流:
文件流包括:
FileInputStream, FileOutputStream --字节流
FileReader, FileWrite --字符流
例子: 读取一个文件的内容并将其输出到显示器上,并统计读取出来的字节的个数
[java] view plain copy
/*
利用FileReader流来读取一个文件中的数据,并在显示器上输出!
*/
import java.io.*;
public class TestFileReader
{
public static void main(String[] args)
{
FileReader fr = null ;
try
{
fr = new FileReader( "C:\\Documents and Settings\\others\\桌面\\java\\TestFileReader.java" );
int cnt = 0 ;
int ch;
while (- 1 != (ch=fr.read())) //20行
{
System.out.print(( char )ch); // System.out.print(int ch); 这是在显示器上输出ch的整数值,所以必须的进行类型转化,我们需要输出的是ch所代表的整数对应的字符
++cnt;
}
System.out.printf( "总共从TestFileReader.java文件中读取了%d个字符" , cnt);
}
catch (FileNotFoundException e)
{
System.out.println( "找不到文件!" );
System.exit(- 1 );
}
catch (IOException e)
{
System.out.println( "文件读取失败!" );
System.exit(- 1 );
}
}
}
FileInputStream 的使用:
InputStream 是用来读取字节的,是个抽象类,我们通常使得的是该类的子类
FiledInputStream 是InputStream的子类,利用FileInputStream可以将一个文件的内容按字节为单位读取出来
FileInputStream 有一个很常用的构造函数 :
public fileInputStream(String fileName)
利用该构造函数可以实现将输入流连接到某个文件的功能
必须对本构造函数抛出异常进行捕捉
如果用字符串来表示扣件系统的文件路径时,我们可以使用\\ 和/两种方式来作为文件夹的路径分隔符
FileOutputStream 同理
缓冲流:
什么是缓冲流:
缓冲流就是带有缓冲区的输入输出流
为什么需要缓冲流:
缓冲流可以显著的减少我们对IO访问的次数,保护我们的硬盘
说明:
缓冲流本身就是处理流(处理流也叫包裹流),缓冲流必须提依附节点流(节点流也叫原始流)
缓冲流要"套接"在相应的节点流上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
缓冲输入流支持其父类的mark和reset方法
BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔 )
BufferedWriter提供了newLine用于写入一行分隔符
对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法会使内存中的数据立刻写出
BufferedOUtputStream 和 BufferedInputStream:
BufferedOutputStream 带缓冲的输出流,允许一次向硬盘写入多个字节的数据
BufferedInputStream 带缓冲的输入流,允许一次向程序中读入多个字节的数据
BufferedOutputStream 和 BufferedInputStream 都是包裹流,必须的依附于OutputStream 和 InputStream
例:
[java] view plain copy
/*
利用BufferedOutputStream 和 BufferedInputStream完成大容量文件的复制
这远比单纯利用 FileInputStream 和 FileOutputStream 要快得多
BufferedOutputStream 和 BufferedInputStream 都是包裹流,必须的依附于
OutputStream 和 OutputStream
*/
import java.io.*;
public class TestBufferedInputStreamOutputStreamCopy
{
public static void main(String[] args)
{
BufferedOutputStream bos = null ;
BufferedInputStream bis = null ;
try
{
bos = new BufferedOutputStream (
new FileOutputStream( "e:/OutputView.txt" )
); //bos 输出流有个默认的缓冲区,大小为32个字节
bis = new BufferedInputStream(
new FileInputStream( "c:\\11.rmvb" )
); //bis 输入流有个默认的缓冲区,大小为32个字节
byte [] buf = new byte [ 1024 ];
int len = bis.read(buf, 0 , 1024 ); //一定要注意,这不是从buf中读数据,而是从bis所关联到的D:\\综艺\\电影\\猫和老鼠\\CD4.rmvb文件中读取数据,并将读取的数据写入bis自己的默认缓冲区中,然后再将缓冲区的内容写入buf数组中,每次最多向buf数组中写入1024个字节,返回实际写入buf数组的字节个数,如果读到了文件的末尾,无法再向buf数组中写入数据,则返回-1
while (- 1 != len)
{
bos.write(buf, 0 , len); //不是写入buf数组,而是将buf数组中下标从0开始的到len-1为止的所有数据写入bos所关联到的"d:/share/OutputView.txt"文件中
len = bis.read(buf); //bis.read(buf); 等价于 bis.read(buf, 0, buf.length);
}
bos.flush();
bis.close();
bos.close();
}
catch (FileNotFoundException e)
{
System.out.println( "没有找到文件!" );
System.exit(- 1 );
}
catch (IOException e)
{
System.out.println( "文件读写错误!" );
System.exit(- 1 );
}
System.out.println( "文件复制成功!" );
}
}
如果我们希望用BufferedInputStream和BufferedOutputStream完成“将一个设备中的数据导入另一个设备中” 我们就就忘定义一个临时的bete类型的数组,用这个临时数组作为输入流与输出流进行交互的中转枢纽
转换流:
Reader
|--InputStreamReader
|--FileReader:专门用于处理文件的字符读取流对象。
Writer
|--OutputStreamWriter
|--FileWriter:专门用于处理文件的字符写入流对象。
特点:
1,是字节流和字符流之间的桥梁。
2,该流对象中可以对读取到的字节数据进行指定编码表的编码转换。
什么时候使用呢?
1,当字节和字符之间有转换动作时。
2,流操作的数据需要进行编码表的指定时。
具体的对象体现:
1,InputStreamReader:字节到字符的桥梁。
2,OutputStreamWriter:字符到字节的桥梁。
这两个流对象是字符流体系中的成员。
那么它们有转换作用,而本身又是字符流。所以在构造的时候,需要传入字节流对象进来。
构造函数:
InputStreamReader(InputStream):通过该构造函数初始化,使用的是本系统默认的编码表GBK。
InputStreamReader(InputStream,String charSet):通过该构造函数初始化,可以指定编码表。
OutputStreamWriter(OutputStream):通过该构造函数初始化,使用的是本系统默认的编码表GBK。
OutputStreamWriter(OutputStream,String charSet):通过该构造函数初始化,可以指定编码表。
操作文件的字符流对象是转换流的子类。
Reader
|--InputStreamReader
|--FileReader
Writer
|--OutputStreamWriter
|--FileWriter
转换流中的read方法。已经融入了编码表,
在底层调用字节流的read方法时将获取的一个或者多个字节数据进行临时存储,
并去查指定的编码表,如果编码表没有指定,
查的是默认码表。那么转流流的read方法就可以返回一个字符比如中文。
转换流已经完成了编码转换的动作,对于直接操作的文本文件的FileReaer而言,就不用在重新定义了,
只要继承该转换流,获取其方法,就可以直接操作文本文件中的字符数据了
Print流:
Print流只有输出流无输入流,PrintWriter和PrintStream分别针对字符字节
两个类提供了重载的Print和Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常
PrintWriter和PrintStream有自动flush功能
----System.setOut(接收OutputStream类):用于设置系统默认输出流
Object流:
等同于c#序列化,用直接将Object写入或读出
transient关键字为不序列化此成员变量
需要序列化的类必须实现Serializable接口
主要方法:writeObject(Object); readObject();
读出为Object类型需要强转数据类型