java io流学习总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
java io流学习总结
(最新版)
编制人:__________________
审核人:__________________
审批人:__________________
编制单位:__________________
编制时间:____年____月____日
序言
下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!
并且,本店铺为大家提供各种类型的实用范文,如工作总结、文秘知识、条据书信、行政公文、活动报告、党团范文、其他范文等等,想了解不同范文格式和写法,敬请关注!
Download tips: This document is carefully compiled by this shop. I hope that after downloading it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you!
In addition, this shop provides you with various types of practical sample essays, such as work summary, secretarial knowledge, article letters, administrative official documents, activity reports, party and group sample essays, other sample essays, etc. If you want to know the format and writing of different sample essays, please pay attention !
正文内容
一、什么是流
流就是字节序列的抽象概念,能被连续读取数据的数据源和能被连续写入数据的接收端就是流,流机制是Java及C++中的一个重要机制,通过流我们可以自由地控制文件、内存、IO设备等数据的流向。
而IO流就是用于处理设备上的数据,如:硬盘、内存、键盘录入等。
IO流根据处理类型的不同可分为字节流和字符流,根据流向的不同可分为输入流和输出流。
二、字节流和字符流的区别:
字符流,因为文件编码的不同,就有了对字符进行高效操作的字符流对象,它的原理就是基于字节流读取字节时去查了指定的码表。
它和字节流的区别有两点:1.在读取数据的时候,字节流读到一个字节就返回一个字节,字符流使用了字节流读到一个或多个字节(一个中文对应的字节数是两个,在UTF-8码表中是3个字节)时,先去查指定的编码表,再将查到的字符返回;2.字节流可以处理所有类型的数据,如jpg、avi、mp3、wav等等,而字符流只能处理字符数据。
所以可以根据处理的文件不同考虑使用字节流还是字符流,如果是纯文本数据可以优先考虑字符流,否则使用字节流。
三、IO体系,所具备的基本功能就是读和写:
1.字符流
|-- Reader(读)
|-- Writer(写)
Reader
|--InputStreamReader
|--FileReader:用于处理文件的字符读取流对象
Writer
|--OutputStreamWriter
|--FileWriter:用于处理文件的字符写入流对象
其实很容易就可以看出来,IO体系中的子类名后缀绝大部分是父类名称,而前缀则是体现子类特有功能的名称。
Reader中常见的方法:
|--int read
读取一个字符,并返回读到的这个字符,读到流的末尾则返回-1。
|--int read(char)
将读到的字符存入指定的数组中,返回的是读到的字符个数,
读到流的末尾则返回-1。
|--close
读取字符其实用的是window系统的功能,就希望使用完毕后,
进行资源的释放。
FileReader除了自己的构造函数外没有特有的方法:
|--用于读取文本文件的流对象。
|--用于关联文本文件。
|--构造函数FileReader(String fileName)
在读取流对象初始化时,必须要指定一个被读取的文件,
如果该文件不存在则会发生FileNotFoundException异常。
Writer中常见的方法:
|--write
将一个字符写入到流中。
|--write(char)
将一个字符数组写入到流中。
|--writer(String)
将一个字符写入到流中。
|--flush
刷新流,将流中的数据刷新到目的地中,流还存在。
|--close
关闭资源,在关闭钱会先调用flush,刷新流中的数据到目的地。
FileWriter,除了自己的构造函数外没有特有的方法:
|--该类的特点
|--用于处理文本文件
|--没有默认的编码表
|--有临时缓冲
|--构造函数,在写入流对象初始化时,必须要有一个存储数据的目的地。
|--FileWriter(String fileName),该构造器是干什么用的呢
|--调用系统资源
|--在指定位置创建一个文件,如果该文件已经存在则被覆盖。
|--FileWriter(String filename,Boolean append),这构造器的作用是
当传入的boolean类型的值为true时,会在指定文件末尾处进行数据的续写。
清单1,将文本数据保存到文件中代码
private static void test1{
FileWriter fw=null;
try {
//初始化FileWriter对象,指定文件名已经存储路径
fw=new FileWriter("D:/test.txt");
fw.write("将字符串写入流");
//将流中的数据刷新到目的地,流还在
fw.flush;
fw.write("将字符串写入流");
} catch (IOException e) {
e.printStackTrace;
}finally{
if(fw!=null){
try {
fw.close;
} catch (IOException e1) {
e1.printStackTrace;
}
}
}
}
清单2,读取一个已有文本文件,并将文本内容打印出来代码
private static void test2{
FileReader fr=null;
try {
//初始化FileReader对象,指定文件路径
fr=new FileReader("D:/test.txt");
int ch=0;
while((ch=fr.read)!=-1){
//每次读取一个字符,直到读到末尾-1为止
System.out.println((char)ch);
}
} catch (IOException e) {
e.printStackTrace;
}finally{
if(fr!=null){
try {
fr.close;
} catch (IOException e1) {
e1.printStackTrace;
}
}
}
}
这样每读到一个字符就打印出来,效率很不高,能不能按指定大小读取完后再打印出来呢答案是当然可以的。
清单3,读取一个已有文本文件,读完1kb再将其读到的内容打印出来代码
private static void test3{
FileReader fr=null;
try {
//初始化FileReader对象,指定文件路径
fr=new FileReader("D:/test.txt");
char buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1){
//每次读取1kb大小的字符,直到读到末尾-1为止System.out.println(new String(buf,0,len)); }
} catch (IOException e) {
e.printStackTrace;
}finally{
if(fr!=null){
try {
fr.close;
} catch (IOException e1) {
e1.printStackTrace;
}
}
}
}
字符流的缓冲区:
|--缓冲区的出现提高了对流的操作效率。
原理:其实就是将数组进行封装。
|--对应的对象
|--BufferedWriter
特有方法newLine,跨平台的换行符。
|--BufferedReader
特有方法readLine,一次读一行,到行标记时,将行标记
之前的字符数据作为字符串返回,读到末尾返回null。
|--说明
在使用缓冲区对象时,要明确,缓冲的存在是为了增强流
的功能而存在,所以在建立缓冲区对象时,要先有流对象
存在。
其实缓冲区内部就是在使用流对象的方法,只不过
加入了数组对数据进行了临时存储,为了提高操作数据的
效率。
|--代码上的体现
|--写入缓冲区对象
根据前面所说的建立缓冲区时要先有流对象,并将其作为参数传递给缓冲区的构造函数
BufferedWriter bufw=new BufferedWriter(new FileWriter(“test.txt”));
bufw.write(“将数据写入缓冲区”);
bufw.flush;//将缓冲区的数据刷新到目的地
bufw.close;//其实关闭的是被包装在内部的流对象
|--读取缓冲区对象
BufferedReader bufr=new BufferedReader(new FileReader(“test.txt”));
String line=null;
while((line=bufr.readLine)!=null){
//每次读取一行,取出的数据不包含回车符
system.out.println(line);
}
bufr.close;
清单4,使用缓冲区对文本文件进行拷贝代码
private static void test4{
BufferedReader bufr=null;
BufferedWriter bufw=null;
try {
bufr=new BufferedReader(new FileReader("D:/a.txt"));
bufw=new BufferedWriter(new FileWriter("D:/b.txt"));
String line=null;
while((line=bufr.readLine)!=null){
bufw.write(line);//每次将一行写入缓冲区
bufw.flush;//刷新到目的地
}
} catch (IOException e) {
e.printStackTrace;
}finally{
try {
if(bufw!=null){
bufw.close;
}
if(bufr!=null){
bufr.close;
}
} catch (IOException e1) {
e1.printStackTrace;
}
}
}
仔细看可以发现,程序里面的FileReader对象和FileWriter对象直接new出来且没有调用close,因为缓冲对象调用了这两个方法,前面说了,缓冲对象调用的flush和close 其实就是关闭被包装在其内部的流对象。
关闭流的先后顺序也要注意,如果流之间有依赖关系,则被依赖的流要后关闭。
readLine 方法原理:其实缓冲区中的该方法,用的还是与缓冲区关联的流对象的read方法,只不过,每一次读到一个字符先不进行具体操作,先进行临时存储,当读到回车标记时,将临时容器中存储的数据一次性返回。
我们可以根据这个原理来自己编写一个缓冲
区对象。
清单5,编写一个自己的bufferedreader代码
public class MyBufferedReader {
private Reader reader;
public MyBufferedReader(Reader reader){
this.reader=reader;
}
public String readLine throws IOException{ StringBuilder sb=new StringBuilder;
int ch=0;
while((ch=reader.read)!=-1){
if(ch=='\r'){//空格则继续
continue;
}else if(ch=='\n'){//每次返回一行
return sb.toString;
}else{
sb.append((char)ch);
}
}
return sb.toString;
}
public void close throws IOException{
//缓冲对象的关闭方法其实就是调用流本身的close
reader.close;
}
}
测试时把清单4的BufferedReader对象替换成MyBufferedReader对象即可。
清单6,测试mybufferedreader代码
private static void test4{
MyBufferedReader bufr=null;
BufferedWriter bufw=null;
try {
bufr=new MyBufferedReader(new FileReader("D:/a.txt"));
bufw=new BufferedWriter(new FileWriter("D:/b.txt"));
String line=null;
while((line=bufr.readLine)!=null){
bufw.write(line);//每次将一行写入缓冲区
bufw.flush;//刷新到目的地
}
} catch (IOException e) {
e.printStackTrace;
}finally{
try {
if(bufw!=null){
bufw.close;
}
if(bufr!=null){
bufr.close;
}
} catch (IOException e1) {
e1.printStackTrace;
}
}
}
其实我们自己写的这个缓存对象就是对Reader对象进行了功能的增强,Reader对象每次只能返回一个字符,而增强了功能之后该类就可以每次返回一行字符,也就是设计模式中所说的装饰模式。