-------android培训、java培训、期待与您交流! ----------
一、字符流
1.Writer
(1).输出流对象
(2).示例:
//创建一个FileWriter对象。该对象一被初始化就要明确被操作的文件,该文件会被创建到指定目录下,
如果该目录已有同名文件,原文件将会被覆盖。
FileWriter fw =
new
FileWriter(
"d:\\demo.txt"
);
fw.write(
"sfsweww"
);
//调用该方法将字符串写入到流中
fw.flush();
//刷新流对象中缓冲区的数据,将数据刷到目的地中
fw.close();
//关闭之前会执行一次刷新
注:每一条语句都会抛出IOException异常,所以必须处理异常。
2.Reader
(1).输入流对象
(2).打印方式:
第一种:
//创建一个文件读取流对象,和指定的名称的文件相关联。要保证该文件是已经存在的。
FileReader fr =
new
FileReader(
"d:\\demo.txt"
);
//调用读取流对象read()方法,一次读取一个字符,而且会自动往下读。
int
c = 0;
while
((c=fr.read()) != -1){
System.
out
.print((
char
)c);
}
fr.close();
第二种:通过字符数组进行读取(此方法较好)
char
[] chs =
new
char
[1024];
//用于存储读取到的字符
int
num = 0;
while
((num=fr.read(chs)) != -1){
//read(char[])返回的是读到字符个数
System.
out
.println(
new
String(chs,0,num));
}
二、字符流的缓冲区
(1).缓冲区的出现是为了提高流的工作效率而出现的。
(2).缓冲区中提供了newLine()这个跨平台的换行方法。
输出数据:
FileWriter fw =
new
FileWriter(
"d:\\demo.txt"
);
BufferedWriter bw =
new
BufferedWriter(fw);
for
(
int
i=0; i<5; i++)
{
bw.write(
"adcd"
);
bw.newLine();
//表示分隔符,是跨平台的
bw.flush();
//只要用到缓冲区就要刷新
}
bw.close();
//其实关闭缓冲区,就是在关闭缓冲区中的流对象
输入数据:
FileReader fr =
new
FileReader(
"d:\\demo.txt"
);
BufferedReader br =
new
BufferedReader(fr);
String buff =
null
;
while
((buff = br.readLine()) !=
null
)
{
System.
out
.println(buff);
}
br.close();
(3).readLine()方法原理:无论是读一行或者是读多个字符,其实最终都是在硬盘上一个一个读取。所以最终还是调用read方法,只不过它把read方法读出来的单个字符先存入一个数组中,遇到换行符的时候,再变成字符串输出。
三、字节流
OutputStream、InputStream
(1).用FileOutputStream输出数据时,不需要刷新操作,但要关闭。
(2).输入和输出方法的用法和Reader的相同。
四、键盘录入
读取转换流(InputStreamReader)
(1).没有用到包装流对象
InputStream in = System.
in
;
StringBuilder sb =
new
StringBuilder();
while
(
true
)
{
int
c = in.read();
if
((
char
)c ==
'\r'
)
continue
;
if
((
char
)c ==
'\n'
)
{
if
(sb.toString().equals(
"over"
))
break
;
System.
out
.println(sb.toString().toUpperCase());
sb.delete(0, sb.length());
}
else
sb.append((
char
)c);
}
(2).用到包装流对象的处理方法(一般用这个)
InputStream in = System.
in
;
InputStreamReader isr =
new
InputStreamReader(in);
BufferedReader br =
new
BufferedReader(isr);
String str =
null
;
while
((str=br.readLine()) !=
null
)
{
if
(str.equals(
"over"
))
break
;
System.
out
. println(str.toUpperCase());
}
br.close();
写入转换流(OutputStreamWriter)
BufferedReader br =
new
BufferedReader(
new
InputStreamReader(System.
in
));
OutputStream os = System.
out
;
OutputStreamWriter osw =
new
OutputStreamWriter(os);
BufferedWriter bw =
new
BufferedWriter(osw);
String str =
null
;
while
((str=br.readLine()) !=
null
)
{
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
什么时候使用转换流?
它是字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。FileReader是InputStreamReader的直接子类,它限定了字符编码为GBK。所以如果要改变字符编码的话,要用其父类 —— InputStreamReader。同理可得FileWriter和OutputStreamWriter的关系。
总结:
流操作的基本规律?
(1).明确源和目的
源:输入流。InputStream、Reader
目的:输出流。OutputStream、Writer
(2).操作的数据是否是纯文本
是:字符流
不是:字节流
(3).当体系明确后,再明确要使用哪个具体的对象。
通过设备来具体区分。
源设备:内存(ByteArrayInput...)、硬盘(FileInput...)、键盘(System.in)
目的设备:内存(ByteArrayOutput...)、硬盘(FileOutput...)、控制台(System.out)
五、打印流
1.
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
2.字节打印流(PrintStream)
构造函数可以接收的类型:
a.file对象
b.字符串路径
c.字节输出流
3.字符打印流(PrintWriter)
构造函数可以接收的类型:
a.file对象
b.字符串路径
c.字节输出流
d.字符输出流
六、管道流(Piped+字符\节流)
1.用于多线程之间的流的操作。
2.管道输入流应该连接到管道输出流。
七、SequenceInputStream
1.没有对应的SequenceOutputStream字节流。
2.此流的作用是用来连接多个流对象,使其组合成一个流对象。
3.构造函数中,可以传Enumeration对象;也可以传InputStream对象,或其子对象;但是第二种方法只能连接两个文件,第一种可以连接多个。(创建Enumeration对象,可以通过Vector来创建,也可以通过匿名内部类来实现Enumeration的接口来实现。)
八、RandomAccessFile(随机读写)
1.概念
(1).该类不是IO体系中的子类,而是直接继承自Object。
(2).它是IO包中的子类,因为它具备读和写的功能。内部封装了一个数组,而且可以通过指针对数组元素进行操作。
(3).可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
(4).完成读写的原理是内部封装了字节输入流和字节输出流。
(5).通过构造方法可知,该类只能操作字节流。而且操作文件还有模式:r、rw
(6).如果模式为只读 r ,不会创建文件。会去读取一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式为 rw ,操作的文件不存在,会自动创建;如果存在,则不会覆盖。
九、DataInputStream、DataOutputStream
1.可以用于操作基本数据类型的数据的流对象。
2.如果使用方法writeUTF(String str)写入的数据,那么如果要读出来时,必须要用对应的读的方法才可以,也就是用readUTF()方法。用其他方法读取失败。
十、操作字节数组的流(ByteArray+InputStream\OutputStream)
1.ByteArrayInputStream:在构造的时候需要接收数据源,而且数据源是一个字节数组。
2.ByteArrayOutputStream:在构造的时候不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的。
3.因为这两个流对象都操作的是数组,并没有使用系统资源。所以不用进行close关闭操作。
4.用流的思想来操作数组。
5.它们的源是内存。