【JAVA IO流之字符流】
2014-10-19 09:14
155 查看
[b]一、概述。[/b]
java对数据的操作是通过流的方式。
java用于操作流的对象都在IO包中。
流按照操作数据不同分为两种,字节流和字符流。
流按照流向分为输入流,输出流。
输入输出的“入”和“出”是相当于内存来说的。
字符流:字节流读取文字字节数据后,不直接操作,而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单来说就是字节流+码表。
在IO流中,字节流的顶层父类是Writer和Reader。
[b]二、java.io.FileWriter类。[/b]
Writer
|--OutputStreamWriter
|--FileWriter
该类是操作字符文件的流,用于将数据写入到文件中。
1.方法摘要
(1).构造方法。
有两个重要的构造方法:
后者相对于前者来说多了一个boolean型的参数,该参数的作用是决定写入文件的方式是追加方式还是覆写方式。
默认的构造方法(前者)构造的FileWriter流对象向文件中写入的时候会默认的将文件的内容清空然后再写入,如果使用后者并将true传入该构造方法,则写入的方式就变成了追加方式。
(2).write方法。
该类没有自己的write方法,全部从父类或者超类中继承而来的write方法。
从OutputStreamWriter中继承而来的方法:
从Writer中继承而来的write方法:
(3).flush方法。
该方法是从OutputStreamWriter中继承而来的,作用是将流中的数据数据刷到文件中。文件关闭前会默认调用此方法。如果不调用此方法,则当缓冲区满了也会自动调用该方法。
(4).close方法。
2.flush与close比较
使用flush方法和close方法均可以保存文件,使用这两者各有什么好处?
举一个形象的例子:我们在使用记事本软件的时候,会常常使用“保存”按钮保存住当前内容到文件,如果没有保存,关闭文件的时候就会出现提示信息“是否要保存文件内容?”,然后再关闭文件。在这个例子中,“保存”相当于flush的功能,而关闭文件则相当于close的功能,经常点保存按钮的目的就是为了防止断电丢失和节约内存。
因此,使用flush的目的就是为了防止断电丢失和节约内存,因此在写程序的时候,尽量写入一句刷新一句;如果文件不关闭,最明显的影响就是“删不掉文件”。
3.FileWriter细节:换行和续写
在Windows字符文件中,文件的换行符是\r\n,在linux中则为\n,这样很有可能导致同一个java程序在linux中的运行结果和在windows中的运行结果不一致。解决方法是使用System类中的方法getProperty,得到当前系统中的行分隔符。具体用法:String line_sparator=System.getProperty("line.separator");
如果想要在已存在的文件末尾添加新内容,则需要使用第二种构造方法。
4.异常处理标准模板。
View Code
此类中,有一句应当特别注意:
在readLine方法中:
这句不能丢,因为丢了这个判断很有可能会丢失最后一行(如果最后一行没有回车)。
通过模拟,可以发现,BufferedReader封装了一个缓冲数组,该缓冲数组缓存r中的数据,以提高程序对数据读取效率。该数组当然也可以自定义,之前已经演示,不赘述。
六、BufferedReader和BufferedWriter类使用了装饰模式
所谓的装饰模式是针对某一类进行功能增强的类。在这里,BufferedReader类对Reader(及其子类)类进行了功能增强,BufferedWriter类对Writer类(及其子类)进行了功能增强。
使用装饰模式和使用继承都能达到增强某一类的功能的目的,但是使用装饰模式更加灵活。装饰模式是针对某一类进行功能增强,而如果使用继承设计模式,则只能针对某个特别的类进行功能增强。比如,如果使用继承达到功能增强的目的,则继承层次将会变成这样:
Reader
|--InputStreamReader
|--FileReader
|--BufferedFileReader
|--BufferedInputStreamReader
相对于原本的继承层次:
Reader
|--InputStreamReader
|--FileReader
|--BufferedReader
来说,前者很明显多了一个缓冲流,但是绝不仅仅是多了一个,因为Reader的子类很多,如果针对每个具体的类进行功能增强,则整个继承体系将会变得非常臃肿。但是如果使用装饰模式进行功能增强,则可以几乎不需要改变原本的继承层次,只需要多出一个缓冲流即可。由此可见,使用装饰模式要灵活很多,因此,如果想要针对某一类进行功能增强,最好使用装饰模式而不是使用继承的方式。
java对数据的操作是通过流的方式。
java用于操作流的对象都在IO包中。
流按照操作数据不同分为两种,字节流和字符流。
流按照流向分为输入流,输出流。
输入输出的“入”和“出”是相当于内存来说的。
字符流:字节流读取文字字节数据后,不直接操作,而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单来说就是字节流+码表。
在IO流中,字节流的顶层父类是Writer和Reader。
[b]二、java.io.FileWriter类。[/b]
public class FileWriterextends OutputStreamWriter |
|--OutputStreamWriter
|--FileWriter
该类是操作字符文件的流,用于将数据写入到文件中。
1.方法摘要
(1).构造方法。
有两个重要的构造方法:
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。 |
FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。 |
默认的构造方法(前者)构造的FileWriter流对象向文件中写入的时候会默认的将文件的内容清空然后再写入,如果使用后者并将true传入该构造方法,则写入的方式就变成了追加方式。
(2).write方法。
该类没有自己的write方法,全部从父类或者超类中继承而来的write方法。
从OutputStreamWriter中继承而来的方法:
void | write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 |
void | write(int c) 写入单个字符。 |
void | write(String str, int off, int len) 写入字符串的某一部分。 |
void | write(char[] cbuf) 写入字符数组。 |
void | write(String str) 写入字符串。 |
void | flush() 刷新该流的缓冲。 |
(4).close方法。
void | close() 关闭此流,但要先刷新它。 |
使用flush方法和close方法均可以保存文件,使用这两者各有什么好处?
举一个形象的例子:我们在使用记事本软件的时候,会常常使用“保存”按钮保存住当前内容到文件,如果没有保存,关闭文件的时候就会出现提示信息“是否要保存文件内容?”,然后再关闭文件。在这个例子中,“保存”相当于flush的功能,而关闭文件则相当于close的功能,经常点保存按钮的目的就是为了防止断电丢失和节约内存。
因此,使用flush的目的就是为了防止断电丢失和节约内存,因此在写程序的时候,尽量写入一句刷新一句;如果文件不关闭,最明显的影响就是“删不掉文件”。
3.FileWriter细节:换行和续写
在Windows字符文件中,文件的换行符是\r\n,在linux中则为\n,这样很有可能导致同一个java程序在linux中的运行结果和在windows中的运行结果不一致。解决方法是使用System类中的方法getProperty,得到当前系统中的行分隔符。具体用法:String line_sparator=System.getProperty("line.separator");
如果想要在已存在的文件末尾添加新内容,则需要使用第二种构造方法。
4.异常处理标准模板。
class MyBufferedReader
{
private Reader r;
private int size=1024;//默认的缓冲区大小
private char buf[];//存放字符的缓冲数组
private int pos=0;//记录当前的指针
private int count=0;//记录数组的长度
public MyBufferedReader(Reader r)
{
this.r=r;
buf=new char[size];
}
public MyBufferedReader(Reader r,int size)
{
this.r=r;
this.size=size;
buf=new char[size];
}
public int read() throws IOException
{
if(count==0)
{
count=r.read(buf);
pos=0;
}
if(count<0)
return -1;
char ch=buf[pos];
pos++;
count--;
return ch;
}
public String readLine() throws IOException
{
StringBuilder sb=new StringBuilder();
int ch;
while((ch=read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
sb.append((char)ch);
}
if(sb.length()!=0)//这里进行健壮性判断是必不可少的,否则很有可能丢失最后一行 return sb.toString();
return null;
}
publicvoid close() throws IOException
{
r.close();
}
}
View Code
此类中,有一句应当特别注意:
在readLine方法中:
if(sb.length()!=0)//这里进行健壮性判断是必不可少的,否则很有可能丢失最后一行 return sb.toString();
这句不能丢,因为丢了这个判断很有可能会丢失最后一行(如果最后一行没有回车)。
通过模拟,可以发现,BufferedReader封装了一个缓冲数组,该缓冲数组缓存r中的数据,以提高程序对数据读取效率。该数组当然也可以自定义,之前已经演示,不赘述。
六、BufferedReader和BufferedWriter类使用了装饰模式
所谓的装饰模式是针对某一类进行功能增强的类。在这里,BufferedReader类对Reader(及其子类)类进行了功能增强,BufferedWriter类对Writer类(及其子类)进行了功能增强。
使用装饰模式和使用继承都能达到增强某一类的功能的目的,但是使用装饰模式更加灵活。装饰模式是针对某一类进行功能增强,而如果使用继承设计模式,则只能针对某个特别的类进行功能增强。比如,如果使用继承达到功能增强的目的,则继承层次将会变成这样:
Reader
|--InputStreamReader
|--FileReader
|--BufferedFileReader
|--BufferedInputStreamReader
相对于原本的继承层次:
Reader
|--InputStreamReader
|--FileReader
|--BufferedReader
来说,前者很明显多了一个缓冲流,但是绝不仅仅是多了一个,因为Reader的子类很多,如果针对每个具体的类进行功能增强,则整个继承体系将会变得非常臃肿。但是如果使用装饰模式进行功能增强,则可以几乎不需要改变原本的继承层次,只需要多出一个缓冲流即可。由此可见,使用装饰模式要灵活很多,因此,如果想要针对某一类进行功能增强,最好使用装饰模式而不是使用继承的方式。
相关文章推荐
- Java IO流 文件的复制的几种方法(字节流,字符流,缓冲流)
- Java IO流 字节流与字符流
- Java IO流(二)--字符流
- Java IO流 字符流 与 转换流 详解
- 【Java IO流】字节流和字符流的实例讲解
- Java IO流->节点流->字符流:FileReader与FileWriter
- Java IO流->处理流->缓冲流->字节流&字符流
- java io流二-字符流输入输出缓冲区
- Java IO流--字符流
- java IO流(字节流与字符流对文件的处理)
- java io流(字符流) 文件打开、读取文件、关闭文件
- java IO流字符流FileReader操作
- java IO流之字符流 v_1.0.0
- JavaScript中生成HTML的字符格式函数
- SQL 利用系统函数 取md5 加密字符
- C# 判断文件名中是否有非法字符
- 判断字符串中的字符大小写和其他字符
- 删除字符串中多余的空白字符和空行(C语言实现)
- PHP中比较两个字符串找出第一个不同字符位置例子
- Sql Server字符的处理(LastIndexOf用法),STUFF、CHARINDEX、REVERSE、LEN