一 文件节点流:
FileInputStream
和
FileOutputStream
是文件字节流,是一种节点流
文件字节输入流的构造方法:
FileInputStream("文件名称
")
,如果文件不存在则
FileNotFoundException
FileInputStream(File)
文件字节输出流的构造方法
:
FileOutputStream(“文件名称
”)
如果文件不存在则新建文件,如果文件存在则覆盖文件内容
FileOutputStream(String name文件名称
, boolean append
是否采用追加方式
)
FileReader
和
FileWriter
类似:
FileInputStream和
FileOutputStream
两个类属于结点流,第一个类的源端和第二个类的目的端都是磁 盘文件,它们的构造方法允许通过文件的路径名来构造相应的流。
如:
FileInputStream infile = new FileInputStream("myfile.dat");
FileOutputStream outfile = new FileOutputStream("results.dat");
要注意的是,构造
FileInputStream,
对应的文件必须存在并且是可读的,而构造
FileOutputStream
时,
如输出文件已存在,则必须是可覆盖的。
要求:将
d
盘上的
TestFile.java
拷贝到
e
盘,并命名为
dd.txt
try ( InputStream is = new FileInputStream ( "d:/TestFile.java" );OutputStream os = new FileOutputStream ( "e:\\dd.txt" );) {byte [] buffer = new byte [ 8192 ];int len = is . read ( buffer );while ( len > 0 ){os . write ( buffer , 0 , len );len = is . read ( buffer );}} catch ( IOException e ){e . printStackTrace ();}构造输出文件流时可以使用两种不同的方式OutputStream os = new FileOutputStream ( "e:\\dd.txt" ); 如果文件不存在则自动创建;如果文件存在则进行覆盖OutputStream os = new FileOutputStream ( "e:\\dd.txt" , true ), 这里的 boolean 类型参数表示是否采用追加的方式写入文件
二 内存数组节点:
如果文本则使用
char[]
,如果二进制则使用
byte[]
构造器方法
CharArrayReader(char[] buf)其中
char[]
就是数据的来源,也就是说
Reader
就是从
char[]
中读取数 据
CharArrayRead(char[] buf, int offset, int length)
CharArrayWriter
用于实现向一个字符数组中写入数据,这个数组可以自动调整大小
ByteArrayInputStream
、
ByteArrayOutputStream
和
CharArrayReader
以及
CharArrayWriter
类似,支 持操作的内容不同而已,操作byte[]
与
char[]
三 内存字串流:
StringReader
用于从一个字串
String
中读取数据
String str = " 亚洲说: ‘ 我爱小黑 ’" ;StringReader sr = new StringReader ( str );int cc ;while (( cc = sr . read ()) !=- 1 )System . out . print (( char ) cc );sr . close ();
StringWriter用于给一个StringBuffer中写入数据,实现一个可边长的字串:
Scanner sc = new Scanner ( System . in );try (StringWriter sw = new StringWriter ();Writer fw = new FileWriter ( "c:/console.txt" )){String temp = sc . nextLine ();while ( ! temp . equals ( "quit" )){if ( temp != null && temp . trim (). length () > 0 )sw . write ( temp + "\n" );temp = sc . nextLine ();}fw . write ( sw . toString ());}
总结:
读写文件使用节点流FileInputStream/FileOutputStream
和
FileReader/FileWriter
,如果操作文本 文件,建议使用FileReader/FileWriter
,如果操作二进制文件建议使用
FileInputStream/FileOutputStream
需要建立缓冲区(
建立临时文件的方式效率低
),
可以考虑使用内存节点,例如
CharArrayReader/CharArrayWriter,
StringReader/StringWriter
ByteArrayInputStream/ByteArrayOutputStream
如果需要一个二进制缓冲区可以使用ByteArrayInputStream/ByteArrayOutputStream
,如果需要 一个字符缓存可以使用CharArrayReader/CharArrayWriter
、
StringReader/StringWriter
如果数据量不是特别大使用CharArrayReader/CharArrayWriter
更为方便,如果数据量大而且可能 需要直接操作缓冲区则使用StringReader/StringWriter
StringWriter中提供了方法
getBuffer():StringBuffer
四 过滤流类型:
过滤流就是在节点流的基础上附加功能
五 过滤流:
就是decorate模式中的抽象装饰角色
FilterInputStream/FilterOutputStream和FilterReader/FilterWriter
所谓的过滤流实际上就是类似上面的加密处理,在输入之后(后置处理,被装饰对象先执行)或者输出
之前(前置处理,先处理然后被装饰对象执行)进行一下额外的处理,最终实际操作是调用被装饰对象
的方法完成工作,依靠这种装饰模式实现在节点流的基础上附加额外功能
.
当然也允许多个过滤流嵌套从
而达到功能累加的目的
FilterInputStream
实际上就是一个装饰抽象角色
自定义流实现循环
13
加密
:
读取数据不变
:FileReader---BufferedReader
写出数据自定义过滤流
SecurityWriter(FilterWriter)
public class SecurityWriter extends FilterWriter {protected SecurityWriter ( Writer out ) {super ( out );}public void write ( int c ) throws IOException {if ( c >= 'a' && c <= 'z' ) {c = ( c - 'a' + 13 ) % 26 + 'a' ;} else if ( c >= 'A' && c <= 'Z' ) {c = ( c - 'A' + 13 ) % 26 + 'A' ;}super . write ( c );}}
public class SecurityReader extends FilterReader {protected SecurityReader ( Reader in ) {super ( in );}public int read () throws IOException {int c = super . read ();if ( c >= 'a' && c <= 'z' ) {c = ( c - 'a' + 13 ) % 26 + 'a' ;} else if ( c >= 'A' && c <= 'Z' ) {c = ( c - 'A' + 13 ) % 26 + 'A' ;}return c ;}}
六 桥接转换流:
InputStreamReader和OutputStreamWriter是java.io包中用于处理字符流的最基本的类,用来在字节
流和字符流之间作为中介:从字节输入流读入字节,并按编码规范转换为字符;往字节输出流写字符时 先将字符按编码规范转换为字节。使用这两者进行字符处理时,在构造方法中应指定一定的平台规范, 以便把以字节方式表示的流转换为特定平台上的字符表示。
转换流可以在构造时指定其编码字符集
InputStreamReader
用于将一个
InputStream
类型的输入流自动转换为
Reader
字符流
OutputStreamWriter
用于将一个
Writer
字符输出流转换为
OutputStream
字节输出流
InputStreamReader
构造器
InputStreamReader(InputStream)
InputStreamReader(InputStream, String)
InputStreamReader(InputStream, Charset)
InputStreamReader(InputStream, CharsetDecorder)
注意:一般不建议自行设置编码字符集,除非是必须的
七 缓冲流:
缓冲流是套接在响应的节点流之上,对续写的数据提供缓冲的功能,提高读写的效率,同时增加了一些 新方法
以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比 较高的时候,其性能表现不佳。为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到 缓存中的数据读取完毕,再到硬盘中读取。
构造方法
BufferedReader(Reader)
不定义缓存大小,默认
8192
BufferedReader(Reader in, int size)size
为自定义缓冲区的大小
BufferedWriter(Writer)
BufferedWriter(Writer out, int size)size
为自定义缓冲区的大小
BufferedInputStream(InputStream)
BufferedInputStream(InputStream in, int size)size
为自定义缓冲区的大小
BufferedOutputStream(OutputStream)
BufferedOutputStream(OuputStream out, int size)size
为自定义缓冲区的大小
缓冲输入流的方法 :
BuffedReader
提供了一个方法
readLine():String
,但是
BufferedInputStream
中并没有这个
BufferedReader
提供了
readLine
方法用于读取一行字符串,以
\r
或
\n
分割(换行符)
如果读取内容为null
,则表示读取到了流的末尾
readLine方法会自动剔除本行内容末尾的换行符
BufferedWriter
提供了
newLine
方法用于写入一个行分隔符
对于输出的缓冲流,写入的数据会先在内存中缓存,使用
flush
方法会使内存中的数据立即写出
键盘录入
System.in:InputStream
用于指代系统默认的输入设备
—
键盘
方法
read():int
可以实现代码执行到这里则会阻塞等待,只要输入数据为止
过滤流使用必须有对应的节点流,因为过滤流是装饰节点流,不是有具体的操作目标
new BufferedReader(new FileReader(..))
或
new BufferedWriter(new FileWriter())
实际上使用的还是 Reader/Writer那些方法,这里从编码的角度上说,没有任何区别,但是从执行性能上说,比
FileReader/Writer
效率高,可以减少磁盘的读写次数
执行
close
方法会自动关闭被装饰的对象,所以不需要再关闭
FileReader
和
FileWriter
执行
flush
会自动刷新数据到节点流上,但是并没有执行关闭流。针对输出流关闭时会自动先
flush
缓存再
执行关闭