Java IO3:字符流

时间:2021-06-03 19:08:50

字符流

字节流提供了处理任何类型输入/输出操作的功能(对于计算机而言,一切都是0 和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,一个Unicode字符占用2个字节,而字节流 一次只能操作一个字节。既然Java的一个主要目的是支持“ 只写一次,到处运行” 的哲学,包括直接的字符输入/输出支持是必要的。字符流层次结构的顶层是Reader 和Writer 抽象类。

• 由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。

字节流一次处理一个字节,字符流一次处理一个字符。

• Java程序语言使用Unicode来表示字符串和字符,Unicode使用两个字节来表示一个字符,即一个字符占16位

Reader
Reader是定义Java的字符输入流的抽象类,该类的所有方法在出错的情况下都将引发IOException。Reader类中有这些方法:

/**
* 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 {/**
* Attempts to read characters into the specified character buffer.
* The buffer is used as a repository of characters as-is: the only
* changes made are the results of a put operation. No flipping or
* rewinding of the buffer is performed.*/
public int read(java.nio.CharBuffer target) throws IOException {
}
/**
* 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 {
}
/**
* 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;/**
* Skips characters. This method will block until some characters are
* available, an I/O error occurs, or the end of the stream is reached.*/
public long skip(long n) throws IOException {
}
/**
* Tells whether this stream is ready to be read.*/
public boolean ready() throws IOException {
}/**
* 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;
}

Writer
Writer是定义字符输出流的抽象类,所有该类的方法都返回一个void值并在出错的条件下引发IOException。Writer类中的方法有:

/**
* 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 a single character. The character to be written is contained in
* the 16 low-order bits of the given integer value; the 16 high-order bits
* are ignored.*/
public void write(int c) throws IOException {
}
/**
* 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());
} /**
* Writes a portion of a string.*/
public void write(String str, int off, int len) throws IOException {
}
/**
* Appends the specified character sequence to this writer.*/
public Writer append(CharSequence csq) throws IOException {
} /**
* Appends a subsequence of the specified character sequence to this writer.*/
public Writer append(CharSequence csq, int start, int end) throws IOException {
} /**
* Appends the specified character to this writer.*/
public Writer append(char c) throws IOException {
} /**
* 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.*/
abstract public void flush() throws IOException; /**
* 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; }

InputStreamReader和OutputStreamWriter类

• 这是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范

An InputStreamReader is a bridge from byte streams to character streams: It
reads bytes and decodes them into characters using a specified
java.nio.charset.Charset charset. The charset that it uses
may be specified by name or may be given explicitly, or the platform's
default charset may be accepted.
An OutputStreamWriter is a bridge from character streams to byte streams:
Characters written to it are encoded into bytes using a specified charset.
The charset that it uses may be specified by name or may be given explicitly,
or the platform's default charset may be accepted.

• InputStreamReader和OutputStreamWriter类的主要构造方法如下
– public InputSteamReader(InputSteam in)
– public InputSteamReader(InputSteamin,String enc)
– public OutputStreamWriter(OutputStream out)
– public OutputStreamWriter(OutputStream out,String enc)

• 其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用
的编码方式)。
• 读写字符的方法read()、 write(),关闭流的方法close()等与Reader和Writer类的同名方法用法都是类似的。

public class StreamTest {
public static void main(String[] args) throws Exception { //字节流
FileOutputStream fos = new FileOutputStream("file.txt"); //变成字符流
OutputStreamWriter osw = new OutputStreamWriter(fos); //加上缓冲功能
BufferedWriter bw = new BufferedWriter(osw); bw.write("http://www.google.com");
bw.write("\n");
bw.write("http://www.baidu.com"); bw.close(); FileInputStream fis = new FileInputStream("file.txt");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr); String str = br.readLine(); while (null != str) {
System.out.println(str); str = br.readLine();
} br.close(); }
}

读取键盘输入

InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);

FileReader和FileWriter

• FileReader类创建了一个可以读取文件内容的Reader类。 FileReader继承于InputStreamReader。 它最常用的构造方法显示如下
– FileReader(String filePath)
– FileReader(File fileObj)
– 每一个都能引发一个FileNotFoundException异常。这里, filePath是一个文件的完整路径,fileObj是描述该文件的File 对象

public class FileReader1 {
public static void main(String[] args) throws Exception {
File file = new File("c:\\CharSet.java");
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String str;
while (null != (str = br.readLine())) {
System.out.println(str);
}
br.close();
}
}

• FileWriter 创建一个可以写文件的Writer类。 FileWriter继承于OutputStreamWriter.它最常用的构造方法如下:
– FileWriter(String filePath)
– FileWriter(String filePath, boolean append)
– FileWriter(File fileObj)
– append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处

• 它们可以引发IOException或SecurityException异常。这里, filePath是文件的完全路径, fileObj是描述该文件的File对象。如果append为true,输出是附加到文件尾的。
• FileWriter类的创建不依赖于文件存在与否。在创建文件之前, FileWriter将在创建对象时打开它来作为输出。如果你试图打开一个只读文件,将引发一个IOException异常

public class FileWriter1 {
public static void main(String[] args) throws IOException {
String str = "hello world welcome nihao hehe"; char[] buffer = new char[str.length()]; str.getChars(0, str.length(), buffer, 0); FileWriter f = new FileWriter("file2.txt"); for (int i = 0; i < buffer.length; i++) {
f.write(buffer[i]);
} f.close();
}
}