Java IO---reader class

Source: Internet
Author: User

In the previous articles have been talking about InputStream, which is the operation of the byte stream class, however, we often in the program to read from the file stream in the character information, if only with Can inputstream read character information? Of course. However, this involves a coding and decoding problem, the transmission must be used in the same encoding method to receive correctly, which results in each time in the transmission, the transmission side need to do a few things:

1) encode the characters that need to be transferred into the specified byte

2) Transmit bytes

The receiver needs to do a few things:

1) Bytes Received

2) decode the bytes into the corresponding characters

Let's take a look at the following example:

I have a file in the corresponding directory, this file is encoded according to Utf-8 , now use inputstream read into a byte array, If we want to read the contents of the file, we also need to continue transcoding the string into the utf-8 format.

Import Java.io.fileinputstream;import Java.io.filenotfoundexception;import Java.io.ioexception;import java.nio.charset.charset;/** * Created by Zhaohui on 16-10-14. */public class Code {public    static void Main (string[] args) {        try {            FileInputStream inputstream = new FILEINP Utstream ("/home/zhaohui/tmp/zhaohui");            byte[] buf = new byte[100];            int length = Inputstream.read (BUF);            System.out.println ("The length of bytes is" + length);            Converts the byte in the specified position in a byte array into the corresponding string,            content = new string (buf, 0, length, charset.forname ("Utf-8"));            System.out.println ("The content is" + content);        } catch (FileNotFoundException e) {            e.printstacktrace ();        } catch (IOException e) {            e.printstacktrace (); c13/>}}}    

Output:

The length of bytes is 16

The content is hello?

From the above example, we see that only InputStream can solve the problem of transmitting strings, but each time to read into byte byte, and then transcoding, trouble, can directly pass the character?????

The answer is: NO!!!

Computers only know 0 and 1, which is byte, and can only transmit byte.

But other people's blog said that Reader and Writer god horse can pass AH? This is different from the angle of understanding, I think I can not pass characters, love how to!

Okay, now I'm going to formally introduce this " can " character Reader( like Writer, I'm not going to say it.)

Let's start with an example of what it would be like if we read the file directly with reader .

Import Java.io.*;import java.nio.charset.charset;/** * Created by Zhaohui on 16-10-14. */public class Code {public    static void Main (string[] args) {        try {            InputStream in = new FileInputStream ("/ho Me/zhaohui/tmp/zhaohui ");            InputStreamReader reader = new InputStreamReader (In, Charset.forname ("utf-16"));            char [] buf = new char[100];            int length = Reader.read (BUF);            System.out.println ("The length is" +length);            for (int i =0;i<length;i++) {                System.out.println ("char [" +i+ "] is" +buf[i]);            }            System.out.println ("The content is" + string.valueof (buf, 0, length));        } catch (FileNotFoundException e) {            e.printstacktrace ();        } catch (IOException e) {            e.printstacktrace (); c15/>}}}    

Output: Thelength is 5

Char [0] is you

Char [1] is good

Char [2] is ?

Char [3] is ?

Char [4] is

The content is hello?


In this way, is not refreshing, that is, when you read the file, using reader can directly specify the decoding method, so that you can directly read the character content. on the issue of coding, more complex, interested please refer to other content on the web, such as Char in java , is two bytes, but if your file is utf-8 , there may be a problem reading characters because Utf-8 characters are variable length, some characters are one byte, some are two, some are three.

Not to say that the computer can only transfer bytes, why here can directly read the characters, good, below I take you in-depth analysis of Reader class.

Say less nonsense, first on the class diagram:


Java Almost every inputstream Span style= "font-family: Arial" > has designed a corresponding reader filereader fileinputstream bufferedreader is also a decorator mode reader receive a reader as parameters, thus to reader provides caching capabilities.

However, in many of the reader , but a part of the useless (personal view), first from The source of reader read:

Public abstract class reader implements readable, closeable {    //read one character at a time public    int read () throws IOException {
   char cb[] = new char[1];        if (read (CB, 0, 1) = =-1)            return-1;        else            return cb[0];    }    Abstract public int read (char cbuf[], int off, int len) throws IOException;        // ...... Omit  ...}

I have only listed two soul functions for Reader, namely read () and read(char cbuf[], int off, int len)

Read () is similar to read ( ) in inputstream , but here is only one character read, and this method calls read ( Char cbuf[], int off, int len), this method is an abstract method, the subclass of reader by implementing this method to achieve the purpose of reading different media.

Next, let's talk about the most important implementation class in the Reader family,theinputstreamreader class.

First look at the structure of this class:


Then let's put some code on it.

public class InputStreamReader extends Reader {private final streamdecoder SD;        Public InputStreamReader (InputStream inch) {super (in); try {sd = Streamdecoder.forinputstreamreader (in, this, (String) null);//# # Check Lock object} catch ( Unsupportedencodingexception e) {//The default encoding should always be available throw new Error        (e);         }} public InputStreamReader (InputStream in, String CharsetName) throws Unsupportedencodingexception {        Super (in);        if (CharsetName = = null) throw new NullPointerException ("CharsetName");    SD = Streamdecoder.forinputstreamreader (in, this, charsetname);    } public int read () throws IOException {return sd.read (); } public int read (char cbuf[], int offset, int length) throws IOException {return sd.read (cbuf, offset, length)    ; }        // ..... Omit ...}

As you can see from the code above,inputstreamreader has an important domain, which is the

Private Final Streamdecoder sd;

This is the domain that helped InputStreamReader solve the problem of coding. In fact, this Streamdecoder class is also a subclass of reader, from the back of the read () method can also be seen, InputStreamReader read () is actually the SD read () method, in the analysis Before Streamdecoder , let's take a look at the InputStreamReader's construction method.

InputStreamReader has four constructors, I'll just say the first two, and I'll take a inputstream as a parameter. The second one charsetname, this is the specified encoding method, the first why not specified? If not specified, the system default encoding is used. This can be seen immediately in the source code of the Streamdecode in the back.

Now let's look at the source code of Streamdecode:

public class Streamdecoder extends the static construction method of Reader {//Streamdecoder, if no encoding is specified, the default encoding public static Streamdecoder for InputStreamReader (InputStream var0, Object var1, String var2) throws Unsupportedencodingexception {string var3 = V        AR2;        if (var2 = = null) {VAR3 = Charset.defaultcharset (). Name (); } try {if (charset.issupported (VAR3)) {return new Streamdecoder (Var0, var1, charset.for            Name (VAR3));        }} catch (Illegalcharsetnameexception var5) {;    } throw new Unsupportedencodingexception (VAR3); } public static Streamdecoder Forinputstreamreader (InputStream var0, Object var1, Charset var2) {return new STR    Eamdecoder (Var0, var1, var2);    } public int read () throws IOException {return this.read0 (); }//Because each character in Java is two bytes, each time it reads two bytes, it is converted to a char type private int read0 () throws IOException {Object var1 = This.loc        K Synchronized (This.lock) {            if (This.haveleftoverchar) {This.haveleftoverchar = false;            return This.leftoverchar;                } else {char[] var2 = new char[2];                int var3 = This.read (var2, 0, 2);                    Switch (VAR3) {case-1: return-1;                        Case 0:default:assert False:var3;                    return-1;                        Case 2:this.leftoverchar = var2[1];                    This.haveleftoverchar = true;                Case 1:return Var2[0]; }            }        }    }}


The core of this class is the Read() method, which can be read out , since it is directly manipulated by the InputStream for read (). 2 bytes, Java every two bytes in a single character.

This is why reader can read characters, but only by using InputStream to read the bytes first, and then transcoding in accordance with a certain encoding, so this is what I said earlier Reader is also unable to read the characters because it is only read bytes, in terms of the turn character.


Finally say this bufferedreader bufferedinputstream similar, It is also a class of decorator patterns, receiving a reader

public class BufferedReader extends reader {    private reader in;    If you do not specify a cache length, the default value of public    BufferedReader (Reader in) {This        (in, defaultcharbuffersize) is used;    }    public int read () throws IOException {        synchronized (lock) {            ensureopen ();            for (;;) {                if (Nextchar >= nchars) {                    fill ();                    if (Nextchar >= nchars)                        return-1;                }                if (SKIPLF) {                    SKIPLF = false;                    if (cb[nextchar] = = ' \ n ') {                        nextchar++;                        Continue;                    }                }                return cb[nextchar++];}}}    

Here we only study its simplest construction method, its constructor receives a Reader object and establishes a cache, and if the cache length is not specified, the default length is used.

BufferedReader 's Soul method Read () and bufferedinputstream () method, all using a fill method, you can refer to java IO-FilterInputStream and decorator mode this article.

If there is no data, use fill to read a piece of data, put in the cache, if there is data in the cache, read directly from the cache OK .

Summary: This article summarizes the use and principle of Reader class, but this article does not specifically involve Java Coding problem, this is a big topic, interested can go online reference other articles.














Java IO---reader class

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.