Reader&Writer
介绍
Reader和Writer分别表示字符输入流和字符输出流,是为了方便高效操作文本文件而产生流操作类。
备注:
Reader和Writer能够完成的操作,InputStream和OutputStream字节流也都能
完成功能。反过来不成立,Reader和Writer只能操作文本文件,二进制文件只能
使用字节流来操作。互联网中有很多时候都是传输和处理文本内容的,所以就出现了字符流
Reader
Reader Code(核心方法)
/**
* Abstract class for reading character streams. The only methods that a
* subclass must implement are read(char[], int, int) and close(). Most
* subclasses, however, will override some of the methods defined here in order
* to provide higher efficiency, additional functionality, or both.
*/
public abstract class Reader implements Readable, Closeable {
/**
* Reads a single character. This method will block until a character is
* available, an I/O error occurs, or the end of the stream is reached.
*/
public int read() throws IOException {
char cb[] = new char[1];
if (read(cb, 0, 1) == -1)
return -1;
else
return cb[0];
}
/**
* Reads characters into an array. This method will block until some input
* is available, an I/O error occurs, or the end of the stream is reached.
*/
public int read(char cbuf[]) throws IOException {
return read(cbuf, 0, cbuf.length);
}
/**
* Reads characters into a portion of an array. This method will block
* until some input is available, an I/O error occurs, or the end of the
* stream is reached.
*/
abstract public int read(char cbuf[], int off, int len) throws IOException;
//该抽象方法是每个实现了Reader的输入流都要实现的方法,和字节输入流
有所不同,字节输入流read()是抽象方法。
/**
* Tells whether this stream is ready to be read.
*
* @return True if the next read() is guaranteed not to block for input,
* false otherwise. Note that returning false does not guarantee that the
* next read will block.
*/
public boolean ready() throws IOException {
return false;
}
/**
* Closes the stream and releases any system resources associated with
* it. Once the stream has been closed, further read(), ready(),
* mark(), reset(), or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*/
abstract public void close() throws IOException;
}
//备注核心方法就是read(char[] chars)
Reader典型用法
@Test
public void testReader() throws Exception {
private static final String SEPARATOR = File.separator;
File inFile = new File("e:" + SEPARATOR + "io" + SEPARATOR + "test.txt");
// 定义文件输入流
Reader reader = new FileReader(inFile);
// 定义字符数组
char[] buffer = new char[1024];
int length = 0;// 定义读入字符数组实际长度
while ((length = reader.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, length));
// 输出文件到控制台时最好不要使用ln换行打印,否则如果数组长度定义不恰当是可能出现问题的。
}
// 释放资源(标准如下)
if (reader != null) {
reader.close();
reader = null;// 尽早让其进GC垃圾回收
}
}
Writer
Writer Code(核心方法)
/**
* Abstract class for writing to character streams. The only methods that a
* subclass must implement are write(char[], int, int), flush(), and close().
* Most subclasses, however, will override some of the methods defined here in
* order to provide higher efficiency, additional functionality, or both.
*/
public abstract class Writer implements Appendable, Closeable, Flushable {
/**
* Writes an array of characters.
* 重点掌握
*/
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
/**
* Writes a portion of an array of characters.
* 重点掌握
*/
abstract public void write(char cbuf[], int off, int len) throws IOException;
/**
* Writes a string.
*/
public void write(String str) throws IOException {
write(str, 0, str.length());
}
/**
* Flushes the stream. If the stream has saved any characters from the
* various write() methods in a buffer, write them immediately to their
* intended destination. Then, if that destination is another character or
* byte stream, flush it. Thus one flush() invocation will flush all the
* buffers in a chain of Writers and OutputStreams.
*
* If the intended destination of this stream is an abstraction provided
* by the underlying operating system, for example a file, then flushing the
* stream guarantees only that bytes previously written to the stream are
* passed to the operating system for writing; it does not guarantee that
* they are actually written to a physical device such as a disk drive.
*/
abstract public void flush() throws IOException;//重点掌握
//flush()这个方法一定要重点掌握,只要有缓冲的输出流如果想及时刷出数
据就一定要手动调用这个方法.其实close方法里面也会调用这个方法的。
/**
* Closes the stream, flushing it first. Once the stream has been closed,
* further write() or flush() invocations will cause an IOException to be
* thrown. Closing a previously closed stream has no effect.
*/
abstract public void close() throws IOException;//重点掌握
}
Writer典型用法
@Test
public void testWriter() throws Exception {
private static final String SEPARATOR = File.separator;
File outFile = new File("e:" + SEPARATOR + "io" + SEPARATOR + "out.txt");
// 定义字符输出流
Writer writer = new FileWriter(outFile);// 默认情况下如果系统已经存在定义文件的话,那么就会覆盖原有文件
// Writer writer=new FileWriter(outFile,boolean append);//是否使用追加模式
// 备注:使用什么模式要谨慎,操作之前最好要先判断系统是否已经存在该文件。
writer.write("helloworld,世界你好");
writer.append("append");
writer.flush();//及时刷出数据
//释放流资源
if (writer != null) {
writer.close();//关闭流资源
writer = null;
}
//备注只要是资源的使用大体上都是这个模板释放
}
使用字符流拷贝文本文件
@Test
public void test() throws Exception {
private static final String SEPARATOR = File.separator;
//定义源文件(输入流)
File inFile = new File("e:" + SEPARATOR + "io" + SEPARATOR + "test.txt");
Reader reader = new FileReader(inFile);
//定义目标文件(输出流)
File outFile = new File("e:" + SEPARATOR + "io" + SEPARATOR + "testCopy.txt");
Writer writer = new FileWriter(outFile);
//定义字符数组
char[] buffer = new char[1024];
int length = 0;//定义实际载入的字符数组长度
while ((length = reader.read(buffer)) != -1) {
writer.write(buffer, 0, length);
}
// 使用Writer是有缓存的,所以必须要刷新缓存才能够把输出流里的数据刷出。
writer.flush();
writer.close();
reader.close();
}
总结
字符流的使用是比较简单的,和字节流使用差不多,但是其更方便高效操作文本
文件。其实java.io流操作的精髓也是从字符流出现之后才开始,之后将会继续学
习到io流里面涉及到的适配器模式和装饰模式。