----------- android培训、java培训、期待与您交流! ------------
I/O : Input/Output 输入输出
IO流即是输入输出流,用来处理设备之间数据的传输、流向
java对数据的操作是通过流的方式
java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流
早期都是字节流,可以处理所有数据。
后期由于文本处理是常见的处理方式,因此设置了字符流。
字符流在内部融合了码表,可以由用户来指定。
常用编码格式有:
ASCII
GBK
unicode
UTF-8
UTF-16
流按流向分为:输入流、输出流
字节流抽象基类:
InputStream
OutputStream
字符流抽象基类:
Reader
Writer
由这四个基类派生出来的子类名称都以其父类名作为后缀,如:
FileInputStream
FileReader
java.io.Writer
java.io.OutputStreamWriter
java.io.FileWriter
OutputStreamWriter 是一个public类,称为转换流。它是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
FileWriter是OutputStreamWriter的唯一子类,用来写入字符文件的便捷类,可以用于写入字符流。
FileWriter没有空参数构造器,必须指定目标文件。没有特有方法。
构造器:
FileWriter(String filename)
创建FileWriter对象:
FileWriter fw = newFileWriter("demo.txt");
注意:指定的文件路径中的\需要转义。
如果指定的文件存在,则,覆盖此文件。
如果指定文件不存在,但路径存在,则会创建此文件。
如果路径不存在,则抛出异常。
创建FileWriter类对象可能会抛出java.io.IOException异常,因此要么throws要么catch。
fw.write("要存入的数据"); //将数据写到流中,此时还没有进文件内
fw.append();//和write差不多,但是可以使用方法调用链
fw.append("abc\r\n").append("def\r\n");
注意:
enter+newline with different platforms:
windows: \r\n
mac: \r
unix/linux: \n
在windows下直接使用\n不能换行,而是显示一个黑方块。这就是使用记事本打开java原码文件格式混乱的原因。
fw.flush(); //刷新流对象中的缓冲区中的数据,清空并将其转入文件中。
close(); //关闭流资源,并刷新缓冲区。
注意:java中的输入流是调用了操作系统的功能(资源),如果不用了一定要close来释放资源。
文件续写:
直接使用FileWriter fw = newFileWriter("demo.txt");时覆盖源文件,如果想在文件后添加内容,则可以使用另一个构造器。
FileWriter fw = newFileWriter("demo.txt", true);
这种方式在文件存在的情况下不会覆盖原文件,而是直接再此文件的内容后添加数据。
java.lang.Object
java.io.Reader
java.io.InputStreamReader
java.io.FileReader
构造器:
FileReader(String filename) throws FileNotFoundException
FileNotFoundException是IOException的一个子类。
当指定的文件不存在时,会抛出此异常。
FileReader fr = newFileReader("demo.txt");
System.out.println(fr.read());
fr.close();
注意:
read()方法用于读取一个字符,但返回的字符是int型的,所以需要强制类型转换(char)fr.read()。
read()方法是依次向后读取,如果读到末尾(文件的结束标记),则返回-1。
读取方式:(一次读一个字符)
int ch = 0;
while((ch = fr.read()) != -1)){
fw.write(ch);
}
另一种读取方式:(一次读2KB)
char[] buffer = new char[1024];
int len = 0;
while((len = fr.read(buffer)) != -1){
fw.write(buffer,0, len);
}
关于IOException 的处理:
可以直接使用throw newRuntimeException();的方式来强制结束程序。
打开多个流时,在finally块中要依次关闭。
练习:
//: IOExceptionDemo.java
//IO异常处理基本格式
import java.io.FileWriter;
import java.io.IOException;
class IOExceptionDemo
{
publicstatic void main(String[] args)
{
FileWriterfw = null;
try{
fw= new FileWriter("demo.txt");
fw.write("我整个人都斯巴达了!\r\n");
fw.append("我整个人都斯巴达了!\r\n").append("这就是斯巴达!!\r\n");
}
catch(IOExceptione){
System.out.println("发生了IO异常!" +e.toString());
}
finally{
try{
if(fw!= null)
fw.close();
}
catch(IOExceptione){
System.out.println("发生了IO异常!" +e.toString());
}
}
}
}
//: FileReaderDemo.java
//读取文本文件
import java.io.FileReader;
import java.io.IOException;
class FileReaderDemo {
publicstatic void main(String[] args) {
FileReaderfr = null;
try{
fr= new FileReader("demo.txt");
char[]buffer = new char[1024];
intnum = 0;
while((num= fr.read(buffer)) != -1)
System.out.println(newString(buffer, 0, num));
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
finally{
try{
if(fr!= null)
fr.close();
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
}
}
}
//: CopyTextDemo.java
//分别使用单字符的buf,和char[]进行文本文件的复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
class CopyTextDemo{
publicstatic void main(String[] args) {
copyChar();
copyCharArr();
}
publicstatic void copyChar(){
FileReaderfr = null;
FileWriterfw = null;
try{
fr= new FileReader("demo.txt");
fw= new FileWriter("d:\\demo.txt");
intch = 0;
while((ch = fr.read()) != -1)
fw.write(ch);
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
finally{
try{
if(fr != null)
fr.close();
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
try{
if(fw!= null)
fw.close();
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
}
}
publicstatic void copyCharArr(){
FileReaderfr = null;
FileWriterfw = null;
try{
fr= new FileReader("demo.txt");
fw= new FileWriter("d:\\demo.txt", true);
char[]buffer = new char[1024];
intnum = 0;
while((num = fr.read(buffer)) != -1)
fw.write(buffer,0, num);
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
finally{
try{
if(fr != null)
fr.close();
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
try{
if(fw!= null)
fw.close();
}
catch(IOException e){
System.out.println("发生了IO异常::" +e.toString());
}
}
}
}
BufferedWriter
java.lang.Object
java.io.Writer
java.io.BufferedWriter
它没有空参数构造器,在创建对象时必须指定目标Writer对象。
这是因为缓冲区是为了提高流的操作效率而出现的。
所以在创建缓冲区之前,必须先有流对象。
构造器:
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz)
创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
方法:
voidclose()
关闭此流,但要先刷新它。
voidflush()
刷新该流的缓冲。
void newLine()
写入一个行分隔符。
voidwrite(char[] cbuf, int off, int len)
写入字符数组的某一部分。
voidwrite(int c)
写入单个字符。
voidwrite(String s, int off, int len)
写入字符串的某一部分。
write方法可以用于写入字符、字符串、字符数组。
BufferedReader
java.lang.Object
java.io.Reader
java.io.BufferedReader
使用上与BufferedWriter大致相同。
包含特殊方法:
String readLine()读取一个文本行。
练习:
//: BufferedTest.java
//使用字符缓冲流进行文本文件复制操作
import java.io.*;
class BufferedTest
{
publicstatic void main(String[] args)
{
BufferedReaderbuffr = null;
BufferedWriterbuffw = null;
try
{
buffr= new BufferedReader(new FileReader("demo.txt"));
buffw= new BufferedWriter(new FileWriter("buffDemo.txt"));
Stringstr = null;
while((str= buffr.readLine()) != null){
buffw.write(str);
buffw.newLine();
buffw.flush();
}
}
catch(IOException e)
{
thrownew RuntimeException("文件复制发生错误");
}
finally{
if(buffr!= null){
try
{
buffr.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输入流时发生错误");
}
}
if(buffw!= null){
try
{
buffw.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输出流时发生错误");
}
}
}
}
}
自定义类模拟字符缓冲流:
//: MyBufferedReaderTest.java
//使用自定义类模拟BufferedReader功能
import java.io.*;
class MyBufferedReader
{
Readerfr;
MyBufferedReader(Readerfr){
this.fr= fr;
}
publicString readLine() throws IOException{
StringBuildersb = new StringBuilder();
intch = 0;
while((ch= fr.read()) != -1){
if(ch== '\r')
continue;
if(ch== '\n')
returnsb.toString();
else
sb.append((char)ch);
}
if(sb.length()!= 0)
returnsb.toString();
returnnull;
}
publicvoid close() throws IOException{
fr.close();
}
}
class MyBufferedReaderTest
{
publicstatic void main(String[] args)
{
MyBufferedReaderbuffr = null;
BufferedWriterbuffw = null;
try
{
buffr= new MyBufferedReader(new FileReader("demo.txt"));
buffw= new BufferedWriter(new FileWriter("123.txt"));
Stringstr = null;
while((str= buffr.readLine()) != null){
buffw.write(str);
buffw.newLine();
buffw.flush();
}
}
catch(IOException e)
{
thrownew RuntimeException("文件复制发生错误");
}
finally{
if(buffr!= null){
try
{
buffr.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输入流时发生错误");
}
}
if(buffw!= null){
try
{
buffw.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输出流时发生错误");
}
}
}
}
}
当想要对已有的对象进行功能增强时,
可以定义一个新类,将已有对象传入(组合),基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。
装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。
所以装饰类和被装饰类通常都属于一个体系中,表示只要只某某的子类,我全能进行增强。
事实上字符缓冲流使用的就是装饰设计模式。
java.lang.Object
java.io.Reader
java.io.BufferedReader
java.io.LineNumberReader
LineNumberReader是BufferedReader的子类,包含父类的所有功能。
在此基础上,还添加了两个新方法:
int getLineNumber() //获取当前行号
void setLineNumber() //设置当前行号
设计自定义类模拟LineNumberReader的功能:
//: MyLineNumberReader.java
//自定义类模拟LineNumberReader类
import java.io.*;
class MyLineNumberReader extendsMyBufferedReader
{
privateint lineNumber = 0;
publicMyLineNumberReader(Reader r){
super(r);
}
publicint getLineNumber(){
returnlineNumber;
}
publicvoid setLineNumber(int num){
this.lineNumber= num;
}
publicString readLine() throws IOException{
lineNumber++;
returnsuper.readLine();
}
publicstatic void main(String[] args)
{
MyLineNumberReadermyline = null;
BufferedWriterbw = null;
try
{
myline= new MyLineNumberReader(new FileReader("demo.txt"));
bw= new BufferedWriter(new FileWriter("myline.txt"));
Stringstr = null;
while((str = myline.readLine()) != null)
{
bw.write(myline.getLineNumber()+ ": " + str);
bw.newLine();
bw.flush();
}
}
catch(IOException e)
{
thrownew RuntimeException("读写文件时发生错误");
}
finally{
if(myline!= null){
try
{
myline.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输入流时发生错误");
}
}
if(bw!= null){
try
{
bw.close();
}
catch(IOException e)
{
thrownew RuntimeException("关闭输出流时发生错误");
}
}
}
}
}
----------- android培训、java培训、期待与您交流! ------------