Java IO streaming learning
Java IO streaming learning
Classes or interfaces related to Java stream operations:
Java flow class diagram structure:
Concept and function of stream stream is a set of bytes with sequence, starting point and ending point. It is the general name or abstraction of data transmission. That is, the transmission of data between two devices is called flow. The essence of flow is data transmission. According to the characteristics of data transmission, the flow is abstracted into various types to facilitate more intuitive data operation.
The device files involved in io include files, consoles, network links, etc. according to the direction of the flow, the device files at both ends can be divided into data source objects and receiving end objects
The IO stream actually shields the details of data processing in the actual equipment. These processing methods are also called communication methods, which can include sequence, random access, buffer, binary, by character, by byte, by line, etc.
The wisest way is to try to use reader and writer as much as possible. Once the program code cannot be compiled successfully, we will find that we have to use byte oriented class libraries.
Java provides classes for processing streams for different situations, so that we can intuitively operate data. These classes are in the IO package of Java. The following describes the classes of the Java IO package. The entire IO package uses a lot of decoration patterns. In the actual use process, constructors involving multi-layer application must have their own architecture of decoration mode, including decorated classes (original construction base classes), decorated superclasses and decorated concrete classes. Knowing how to distinguish and understand them in the process of use will make you use them more flexibly.
be careful:
We know that before the character stream processing classes were added to the Java IO class library, all classes were byte stream oriented. In jdk1 After 1, character stream support was added. According to the "opening and closing principle", on the basis of not changing the original classes, there are conversion streams: inputstreamreader and outputstreamwriter. These two classes are the so-called "adapter classes". Inputstreamreader can convert InputStream into reader, and outputstreamwriter can convert OutputStream into writer. Byte stream and character stream have their own independent set of inheritance hierarchy, and through the adapter class, they can be effectively combined without changing the original class.
The Java I / O class library requires a combination of many different functions. The reason for the existence of the filter class is that the abstract class filter is the base class of all decorator classes, and the decorator must have the same interface as the object it decorates. Filterinputstream and filteroutputstream are used to provide decorator class interfaces to control specific input streams and output streams The names of the two classes of (OutputStream) are not very intuitive, including datainput / OutputStream, bufferedinput / OutputStream, linenumberinputstream, pushbackinputstream, printstream, etc. These filter stream classes are described in detail below. Filterinputstream and filteroutputstream are derived from the base classes InputStream and OutputStream in the I / O class library respectively Two classes are necessary for decorators (so that they can provide a common interface for all objects being decorated).
Node streams are directly connected to data sources for IO operations. Files are the most common data sources. The following describes the contents related to files.
The file class can represent a file or a folder directory. Just show a piece of code directly+< span class="hljs-keyword">import java. io.< span class="hljs-type">File;
File stream includes four types of input and output character bytes. First, let's look at file byte stream processing.
+<span class="hljs-keyword">import java.io.<span class="hljs-type">BufferedOutputStream;
<span class="hljs-comment">/**
-
字节流的学习
-
基于字节I/O操作的基类:InputStream和OutputStream
-
对应的缓存类:BufferedInputStream和BufferedOutputStream
-
出入的主语是“内存”,出内存就是写入文件,入内存就是读取文件
-
@author Evsward
-
*/
public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">ByteStreamS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-meta">@Test
<span class="hljs-comment">/**-
使用输出流OutputStream.write,将内存中的内容写入设备文件(这里的设备文件为File:磁盘文件)
*/
public void testWrite2OutputStream() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-type">OutputStream fos = <span class="hljs-keyword">new <span class="hljs-type">FileOutputStream(root+<span class="hljs-string">"/UME.txt");<span class="hljs-comment">//找不到该文件会自动创建(包括路径)
<span class="hljs-comment">/**- 内容中的字符串内容content
*/
<span class="hljs-type">String content = <span class="hljs-string">"哈哈哈\n嘿嘿";
fos.write(content.getBytes());<span class="hljs-comment">// 直接写入字节
fos.close();<span class="hljs-comment">// 操作完注意将流关闭
<span class="hljs-comment">/**
- 文件后面追加内容,构造函数加第二个参数true
*/
<span class="hljs-type">OutputStream fosadd = <span class="hljs-keyword">new <span class="hljs-type">FileOutputStream(root+<span class="hljs-string">"/UME.txt",<span class="hljs-literal">true);
fosadd.write(<span class="hljs-string">" 你好".getBytes());
fosadd.close();
}
- 内容中的字符串内容content
<span class="hljs-meta">@Test
<span class="hljs-comment">/**- 使用输入流读取InputStream.read,将设备文件(这里的磁盘文件是File)读到内存buffer中去。
*/
public void testRead2InputStream() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
int bufferSize = <span class="hljs-number">200;
<span class="hljs-type">FileInputStream fis = <span class="hljs-keyword">new <span class="hljs-type">FileInputStream(root+<span class="hljs-string">"/UME.txt");
byte buffer[] = <span class="hljs-keyword">new byte[bufferSize];
int length;
<span class="hljs-keyword">while ((length = fis.read(buffer,<span class="hljs-number">0,bufferSize)) > <span class="hljs-number">-1) {
<span class="hljs-type">String str = <span class="hljs-keyword">new <span class="hljs-type">String(buffer,length);
logger.info(str);
}
fis.close();<span class="hljs-comment">// 操作完注意将流关闭
<span class="hljs-comment">/**- 输出:
- 13:41:02[testInputStreamS]: 举杯邀明月床前明月光
*/
}
}
-
The data stream can be stored in the memory buffer after being processed from the data source, and then operated with the underlying IO at one time, which can effectively reduce the frequency of direct IO operation by the program and improve the execution speed of Io. The following is the use of buffer processing streams.
缓冲区处理流:BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,* 一次性写入,降低占用IO的频率
<="" li="">避免每次和硬盘打交道,提高数据访问的效率。
*/
@<span class="hljs-function">Test
<span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">testWrite2BufferedOutputStream<span class="hljs-params">() throws IOException {
<span class="hljs-comment">// OutputStream为基类
OutputStream fosaddOnce = <span class="hljs-keyword">new FileOutputStream(root+<span class="hljs-string">"/UME.txt");
OutputStream bs = <span class="hljs-keyword">new BufferedOutputStream(fosaddOnce);
bs.write(<span class="hljs-string">"举杯邀明月".getBytes());
bs.flush();<span class="hljs-comment">// 每次flush会将内存中数据一齐刷入到外部文件中,但不会close该流。
bs.write(<span class="hljs-string">"床前明月光".getBytes());
<span class="hljs-comment">/**
- close方法除了有关闭流的作用,在其关闭流之前也会执行一次flush。
- 注意一定要先关闭BufferedOutputStream,再关闭FileOutputStream,从外到内打开,要从内到外关闭。
*/
bs.close();
fosaddOnce.close();<span class="hljs-comment">// 两个流都要关闭
}
Next, let's look at the processing of character stream, which also includes the application of file character read-write stream (filewriter / FileReader).
+<span class="hljs-keyword">import java.io.<span class="hljs-type">BufferedReader;
<span class="hljs-comment">/**
字符流的学习
基于字符I/O操作的基类: Reader和Writer
对应的缓存类:BufferedReader和BufferedWriter
@author Evsward
*/
public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">CharacterStreamS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-meta">@Test
<span class="hljs-comment">/**
OutputStreamWriter,字节到字符的转化桥梁,转化过程中需指定编码字符集,否则采用默认字符集。
*/
public void testWriter() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-comment">// 文件输出流不变
<span class="hljs-type">FileOutputStream fos = <span class="hljs-keyword">new <span class="hljs-type">FileOutputStream(root + <span class="hljs-string">"HongXing.txt");
<span class="hljs-comment">/**
- 输出流写入类(这是比起字节流多出来的类)专门用来写入字符流,注意字符编码的参数
- 如果只保留fos一个参数,编码默认为工作区默认编码,这里是“UTF-8",
- 字节编码为字符 -> 请转到 http://www.cnblogs.com/Evsward/p/huffman.html#ascii编码
- 为了保证写入和读取的编码统一,请每次都要指定编码
- 输出体系中提供的两个转换流,用于实现将字节流转换成字符流。
*/
<span class="hljs-type">OutputStreamWriter osw = <span class="hljs-keyword">new <span class="hljs-type">OutputStreamWriter(fos);
<span class="hljs-comment">// 缓存写入类,对应BufferedOutputStream
<span class="hljs-type">BufferedWriter bw = <span class="hljs-keyword">new <span class="hljs-type">BufferedWriter(osw);
bw.write(<span class="hljs-string">"感时花溅泪,恨别鸟惊心");
bw.close();
osw.close();
fos.close();<span class="hljs-comment">/**
- 终版:将close部分缩短
*/
<span class="hljs-type">BufferedWriter bwA = <span class="hljs-keyword">new <span class="hljs-type">BufferedWriter(
<span class="hljs-keyword">new <span class="hljs-type">OutputStreamWriter(<span class="hljs-keyword">new <span class="hljs-type">FileOutputStream(root + <span class="hljs-string">"HongXing.txt",<span class="hljs-literal">true),<span class="hljs-string">"UTF-8"));<span class="hljs-comment">// 注意层级,加入指定编码的参数
bwA.write(<span class="hljs-string">"\n烽火连三月,家书抵万金");
bwA.close();
}<span class="hljs-meta">@Test
<span class="hljs-comment">/**
InputStreamReader,字节到字符的转化桥梁,转化过程中需指定编码字符集,否则采用默认字符集。
*/
public void testReader() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-type">FileInputStream fis = <span class="hljs-keyword">new <span class="hljs-type">FileInputStream(root + <span class="hljs-string">"HongXing.txt");
<span class="hljs-comment">/**
- 输出流读取类(这是比起字节流多出来的类)专门用来读取字符流,注意字符编码的参数要与写入时的编码相同,否则会乱码
- 输入体系中提供的两个转换流,用于实现将字节流转换成字符流。
*/
<span class="hljs-type">InputStreamReader isr = <span class="hljs-keyword">new <span class="hljs-type">InputStreamReader(fis,<span class="hljs-string">"UTF-8");
<span class="hljs-type">BufferedReader br = <span class="hljs-keyword">new <span class="hljs-type">BufferedReader(isr);
<span class="hljs-type">String str;<span class="hljs-comment">// 这里也可以用StringBuilder来累计文件的全部内容,最后输出。
<span class="hljs-keyword">while ((str = br.readLine()) != <span class="hljs-literal">null) {
logger.info(str);
}
br.close();<span class="hljs-comment">// 显示调用close方法关闭流
isr.close();
fis.close();<span class="hljs-comment">/**
- 终版:将close部分缩短
*/
<span class="hljs-type">BufferedReader brA = <span class="hljs-keyword">new <span class="hljs-type">BufferedReader(
<span class="hljs-keyword">new <span class="hljs-type">InputStreamReader(<span class="hljs-keyword">new <span class="hljs-type">FileInputStream(root + <span class="hljs-string">"HongXing.txt"),<span class="hljs-string">"UTF-8"));
<span class="hljs-type">String strA;
<span class="hljs-keyword">while ((strA = brA.readLine()) != <span class="hljs-literal">null) {
logger.info(strA);
}
brA.close();<span class="hljs-comment">/**
- 输出: 15:04:07[testReader]: 感时花溅泪,恨别鸟惊心 15:04:07[testReader]:
- 烽火连三月,家书抵万金
*/
}<span class="hljs-comment">/**
- File提供了支持字符读写的封装类:FileWriter和FileReader
- 所以不必每次都使用InputStreamReader和OutputStreamWriter来转换。
*/<span class="hljs-meta">@Test
public void testFileWriter() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-type">FileWriter fw = <span class="hljs-keyword">new <span class="hljs-type">FileWriter(root + <span class="hljs-string">"HongXing.txt",<span class="hljs-literal">true);
fw.write(<span class="hljs-string">"\n杜甫《春望》");
fw.close();
}<span class="hljs-meta">@Test
public void testFileReader() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-type">FileReader fr = <span class="hljs-keyword">new <span class="hljs-type">FileReader(root + <span class="hljs-string">"HongXing.txt");
<span class="hljs-comment">// FileReader直接read方法没有readLine方便,所以套上装饰类BufferedReader借它的readLine用一用
<span class="hljs-type">BufferedReader br = <span class="hljs-keyword">new <span class="hljs-type">BufferedReader(fr);
<span class="hljs-type">String str;
<span class="hljs-keyword">while ((str = br.readLine()) != <span class="hljs-literal">null) {
logger.info(str);
}
br.close();
fr.close();
}
<="" li="">}
Note: file provides encapsulated classes that support character reading and writing: filewriter and FileReader, so you don't have to use inputstreamreader and outputstreamwriter to convert every time.
RandomAccessFile means entering a file at any location. It is applicable to files composed of records with known size. It has a seek method that defines the location of the file. Therefore, it is important to remember the location and size of the file content when RandomAccessFile is operated on the file, otherwise the content replication change will occur+< span class="hljs-keyword">import java. io.< span class="hljs-type">File;
This pair of classes can write java basic type data directly (there is no string), but after writing, it is in the form of a binary file and cannot be viewed directly. Dataoutputstream / datainputstream is a common filter stream class. If the serialization of an object is to convert the whole object into a byte sequence, dataoutputstream / datainputstream serializes the field and converts it into binary data. See the code below. + < span class= "hljs-keyword">import java. io.< span class="hljs-type">BufferedInputStream;
In the process of data transmission, the binary file mode will be adopted by default, because the bottom recognition mode of the computer is binary and does not depend on any running environment or programming language, so this is the basis for realizing cross platform and cross network data transmission. Serialization can directly convert Java objects into a byte sequence, and can completely restore the byte sequence to the original object in the future. This process can even be carried out through the network, which means that the serialization mechanism can automatically make up for the differences between different operating systems. If you want a class object to be serialized successfully, it must implement the serializable interface. This interface is like the clonable interface. They are just an empty identification interface. The following paragraph to describe object serialization is really very enlightening. When you create an object, it will always exist as long as you need it, but it will not continue to exist anyway when the program terminates. Although it certainly makes sense to do so, there are still some cases where it will be very useful if the object can still exist and save its information when the program is not running. In this way, the next time the program runs, the object will be rebuilt and have the same information as it had the last time the program ran. Of course, you can achieve the same effect by writing information into files or databases, but in the object-oriented spirit of making everything object, it will be very convenient if you can declare an object as "persistent" and deal with all the details for us. Compared with the heavyweight persistence of database storage, object serialization can achieve lightweight persistence. Persistence means that the life cycle of an object does not depend on whether the program is executing. It can survive between program calls. Lightweight because you can't simply define an object with a keyword and let the system automatically maintain other details. On the contrary, the object must be serialized and deserialized explicitly in the program. If you need a more stringent persistence mechanism, you can consider tools such as hibernate. Todo: there will be an article to introduce hibernate in depth. The meaning of object serialization: it supports Java Remote method call RMI, which makes objects that live on other computers use as if they live on the local machine. For Java beans, you must save the configuration of their state information at the design stage and restore it later when the program starts. The specific work is completed by object serialization< span class="hljs-comment">/**
First of all, what is the standard input stream of Java? It's InputStream, correct. So what is the standard output stream of Java? Is it OutputStream? No! It's printstream. Because the standard input / output stream is the definition of the system class, there are three fields in the system. In is the InputStream type, which corresponds to the standard input stream. Err and out are printstream objects, and out corresponds to the standard output stream. Our common system out. The return value of the println (data) method is the printstream object. By default, this stream is output on the console. You can also redirect the output location: printwriter is the version of the character operation of printstream. Printstreams operate on byte streams. If you want to operate character streams, you can use printwriter. Let's look directly at the comments of the code+< span class="hljs-keyword">import java. io.< span class="hljs-type">FileOutputStream;
There are two constructors for merging streams:
After merging streams, the operation can be to read and write to another file or print to the console. Here's the code:
+<span class="hljs-keyword">import java.io.FileInputStream;
<span class="hljs-keyword">public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">SequenceInputStreamS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-comment">/** * 合并两个读入的字节流 * * <span class="hljs-doctag">@throws IOException */ <span class="hljs-meta">@Test <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">testSequenceInputStream<span class="hljs-params">() <span class="hljs-keyword">throws IOException { <span class="hljs-comment">// buffer的空间要设定为2的次方才能有效分割,否则会出现某汉字被中途分割显示不完整的情况, <span class="hljs-keyword">int bufferSize = <span class="hljs-number">16; InputStream is1 = <span class="hljs-keyword">new FileInputStream(root + <span class="hljs-string">"UME.txt"); InputStream is2 = <span class="hljs-keyword">new FileInputStream(root + <span class="hljs-string">"HongXing.txt"); SequenceInputStream sis = <span class="hljs-keyword">new SequenceInputStream(is1,is2);<span class="hljs-comment">// 构造参数必须为InputStream <span class="hljs-keyword">byte[] buffer = <span class="hljs-keyword">new <span class="hljs-keyword">byte[bufferSize]; <span class="hljs-keyword">while (sis.read(buffer,bufferSize) != -<span class="hljs-number">1) { <span class="hljs-comment">// 开始读合并后的数据流,这里可以针对这些数据流做任何操作(读写到任何文件或者打印到控制台) String str = <span class="hljs-keyword">new String(buffer,bufferSize); logger.info(str);<span class="hljs-comment">// 打印到控制台 } is1.close(); is2.close(); sis.close(); } <span class="hljs-meta">@Test <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">testMergeEnumInputStream<span class="hljs-params">() <span class="hljs-keyword">throws IOException { <span class="hljs-comment">// 实际上它可以合并不同类型数据,然而如果是对象流的话,读取时涉及反序列化工作,要找准与其他数据的分割点,比较麻烦。 InputStream is1 = <span class="hljs-keyword">new FileInputStream(root + <span class="hljs-string">"UME.txt"); InputStream is2 = <span class="hljs-keyword">new FileInputStream(root + <span class="hljs-string">"HongXing.txt"); InputStream is3 = <span class="hljs-keyword">new FileInputStream(root + <span class="hljs-string">"HuaYi.txt"); ArrayList<InputStream> list = <span class="hljs-keyword">new ArrayList<InputStream>(); list.add(is1); list.add(is2); list.add(is3); Iterator<InputStream> it = list.iterator();<span class="hljs-comment">// 传入一个迭代器用于创建枚举 SequenceInputStream sis = <span class="hljs-keyword">new SequenceInputStream(<span class="hljs-keyword">new Enumeration<InputStream>() { <span class="hljs-meta">@Override <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">boolean <span class="hljs-title">hasMoreElements<span class="hljs-params">() { <span class="hljs-keyword">return it.hasNext(); } <span class="hljs-meta">@Override <span class="hljs-function"><span class="hljs-keyword">public InputStream <span class="hljs-title">nextElement<span class="hljs-params">() { <span class="hljs-keyword">return it.next(); } }); <span class="hljs-keyword">int bufferSize = <span class="hljs-number">32; <span class="hljs-keyword">byte[] buffer = <span class="hljs-keyword">new <span class="hljs-keyword">byte[bufferSize]; <span class="hljs-keyword">while (sis.read(buffer,bufferSize); logger.info(str);<span class="hljs-comment">// 打印到控制台 } is1.close(); is2.close(); is3.close(); sis.close(); }
}
Linenumberreader can add the read character stream to the line number. See the code below.
<span class="hljs-keyword">import java.io.<span class="hljs-type">FileReader;
<span class="hljs-keyword">import java.io.<span class="hljs-type">IOException;
<span class="hljs-keyword">import java.io.<span class="hljs-type">LineNumberReader;<span class="hljs-keyword">import org.junit.<span class="hljs-type">Test;
public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">LineNumberReaderS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-meta">@Test public void testLineNumberReader() <span class="hljs-keyword">throws <span class="hljs-type">IOException { <span class="hljs-type">FileReader fr = <span class="hljs-keyword">new <span class="hljs-type">FileReader(root + <span class="hljs-string">"UME.txt"); <span class="hljs-comment">// 构造参数为Reader <span class="hljs-type">LineNumberReader lnr = <span class="hljs-keyword">new <span class="hljs-type">LineNumberReader(fr); lnr.setLineNumber(<span class="hljs-number">1);<span class="hljs-comment">// 设置行号从2开始。 <span class="hljs-type">String str; <span class="hljs-keyword">while ((str = lnr.readLine()) != <span class="hljs-literal">null) { <span class="hljs-comment">// 核心方法:lnr.getLineNumber(),获得行号 logger.info(<span class="hljs-string">"行号:" + lnr.getLineNumber() + <span class="hljs-string">" 内容:" + str); } fr.close(); lnr.close(); <span class="hljs-comment">/** * 输出: * * 12:11:27[testLineNumberReader]: 行号:2 内容:举杯邀明月 * * 12:11:27[testLineNumberReader]: 行号:3 内容:床前明月光 */ }
}
Push a single character back into the input stream. Here, the array reading method is adopted, which is also divided into bytes and characters. The byte array stream is bytearrayinputstream and the character array stream is chararrayreader.
<span class="hljs-keyword">import java.io.<span class="hljs-type">ByteArrayInputStream;
<span class="hljs-keyword">import java.io.<span class="hljs-type">CharArrayReader;
<span class="hljs-keyword">import java.io.<span class="hljs-type">IOException;
<span class="hljs-keyword">import java.io.<span class="hljs-type">PushbackInputStream;
<span class="hljs-keyword">import java.io.<span class="hljs-type">PushbackReader;<span class="hljs-keyword">import org.junit.<span class="hljs-type">Test;
public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">PushBackS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-meta">@Test
public void testPushbackInputStream() <span class="hljs-keyword">throws <span class="hljs-type">IOException {
<span class="hljs-type">String content = <span class="hljs-string">"Superman VS Batman";
<span class="hljs-comment">// 构造参数为一个字节数组
<span class="hljs-type">ByteArrayInputStream bais = <span class="hljs-keyword">new <span class="hljs-type">ByteArrayInputStream(content.getBytes());
<span class="hljs-comment">// 构造参数为一个InputStream对象。
<span class="hljs-type">PushbackInputStream pbis = <span class="hljs-keyword">new <span class="hljs-type">PushbackInputStream(bais);
pbis.unread(<span class="hljs-string">"Ssdfasdf".getBytes(),<span class="hljs-number">1);<span class="hljs-comment">// 将S推到源字符串的最前方
<span class="hljs-comment">// pr.unread('S');// 这里的'S'是按照整型值操作
int n;
<span class="hljs-type">String str = <span class="hljs-string">"";
<span class="hljs-keyword">while ((n = pbis.read()) != <span class="hljs-number">-1) {
str += (char) n;
<span class="hljs-comment">// pbis.unread(n);将刚读出来的字符再推回去,就会死循环。
}
logger.info(str);
pbis.close();
bais.close();
<span class="hljs-comment">/**
- 输出:
- 12:32:48[testPushBackInputStream]: SSuperman VS Batman
*/
}<span class="hljs-meta">@Test <span class="hljs-comment">/** * PushbackInputStream的字符流版本 */ public void testPushbackReader() <span class="hljs-keyword">throws <span class="hljs-type">IOException { <span class="hljs-comment">// 构造参数为Reader对象,使用字符数组读取 <span class="hljs-type">PushbackReader pr = <span class="hljs-keyword">new <span class="hljs-type">PushbackReader(<span class="hljs-keyword">new <span class="hljs-type">CharArrayReader(<span class="hljs-string">"go go Gan.".toCharArray())); pr.unread(<span class="hljs-string">"Ssdfasdf".toCharArray(),<span class="hljs-number">1);<span class="hljs-comment">// 将S推到源字符串的最前方 <span class="hljs-comment">// pr.unread('S');// 这里的'S'是按照整型值操作 int n; <span class="hljs-type">String str = <span class="hljs-string">""; <span class="hljs-keyword">while ((n = pr.read()) != <span class="hljs-number">-1) { str += (char) n; <span class="hljs-comment">// pr.unread(n);将刚读出来的字符再推回去,就会死循环。 } logger.info(str); pr.close(); <span class="hljs-comment">/** * 输出: * * 12:45:55[testPushbackReader]: Sgo go Gan. */ }
}
There is not much to say about this, that is, the read and write operations of a string are rarely used alone, because they can be replaced by using string directly. However, when a stream is needed, it can be combined with other IO streams.
+<span class="hljs-keyword">import java.io.<span class="hljs-type">IOException;
public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">StringIOS <span class="hljs-keyword">extends <span class="hljs-title">IOBaseS {
<span class="hljs-meta">@Test public void testStringWriter() <span class="hljs-keyword">throws <span class="hljs-type">IOException { <span class="hljs-type">StringWriter sw = <span class="hljs-keyword">new <span class="hljs-type">StringWriter(); sw.write(<span class="hljs-string">"Hello"); sw.append(<span class="hljs-string">"A"); sw.close(); logger.info(sw); <span class="hljs-type">StringReader sr = <span class="hljs-keyword">new <span class="hljs-type">StringReader(<span class="hljs-string">"Hello"); int c; <span class="hljs-type">StringBuilder sb = <span class="hljs-keyword">new <span class="hljs-type">StringBuilder(); <span class="hljs-keyword">while ((c = sr.read()) != <span class="hljs-number">-1) { sb.append((char)c); } logger.info(sb); <span class="hljs-comment">/** * Output: * * 12:56:47[testStringWriter]: HelloA * * 12:56:47[testStringWriter]: Hello */ }
}
Java programming ideas, effective Java, JDK API document