Super detailed sentence by sentence introduction to the file input / output buffer stream function BufferedReader and BufferedWriter function source code of Java advanced interface (full)

1, BufferedReader and BufferedWriter functions The BufferedReader function mainly reads text from the character input st...
1, BufferedReader and BufferedWriter functions
2, BufferedReader source code introduction
3, BufferedWriter function source code introduction

1, BufferedReader and BufferedWriter functions

The BufferedReader function mainly reads text from the character input stream and buffers characters to provide effective reading of characters, arrays and lines. You can specify the buffer size or use the default size. For most purposes, the default value is large enough.
BufferedWriter is mainly used to write text into the character output stream and buffer characters to provide efficient writing of single characters, arrays and strings. You can specify the buffer size or accept the default size. For most purposes, the default value is large enough.
Next, I will introduce these two functions in detail from the perspective of source code.

2, BufferedReader source code introduction

BufferedReader inherits from Reader.

public class BufferedReader extends Reader {

A read in attribute is defined below

private Reader in;

A char array is defined below

private char cb[];

Defines the successor node of the char array

private int nChars, nextChar;

Define some flag fields and their special assignments

private static final int INVALIDATED = -2; private static final int UNMARKED = -1; private int markedChar = UNMARKED; private int readAheadLimit = 0;

The following flag is used to judge whether the field is a newline character. It is false by default

private boolean skipLF = false;

The following fields are used to determine whether to wrap

private boolean markedSkipLF = false;

The following defines the default number of characters and lines in the buffer pool. The default number of characters is 8k and the number of lines is 80

private static int defaultCharBufferSize = 8192; private static int defaultExpectedLineLength = 80;

Creates a buffered character input stream using an input buffer of the specified size.

public BufferedReader(Reader in, int sz) { super(in); if (sz <= 0) throw new IllegalArgumentException("Buffer size <= 0"); this.in = in; cb = new char[sz]; nextChar = nChars = 0; }

Create a default buffer reader

public BufferedReader(Reader in) { this(in, defaultCharBufferSize); }

Check to ensure that the flow has not been closed

private void ensureOpen() throws IOException { if (in == null) throw new IOException("Stream closed"); }

The following function is used to determine whether the buffer is filled

private void fill() throws IOException { int dst; if (markedChar <= UNMARKED) { /* No mark */ dst = 0; } else { /* Marked */ int delta = nextChar - markedChar; if (delta >= readAheadLimit) { /* Gone past read-ahead limit: Invalidate mark */ markedChar = INVALIDATED; readAheadLimit = 0; dst = 0; } else { if (readAheadLimit <= cb.length) { /* Shuffle in the current buffer */ System.arraycopy(cb, markedChar, cb, 0, delta); markedChar = 0; dst = delta; } else { /* Reallocate buffer to accommodate read-ahead limit */ char ncb[] = new char[readAheadLimit]; System.arraycopy(cb, markedChar, ncb, 0, delta); cb = ncb; markedChar = 0; dst = delta; } nextChar = nChars = delta; } } int n; do { n = in.read(cb, dst, cb.length - dst); } while (n == 0); if (n > 0) { nChars = dst + n; nextChar = dst; } }

The function to read one character is defined below

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++]; } } }

The following function is used to read a part of the character array

private int read1(char[] cbuf, int off, int len) throws IOException { if (nextChar >= nChars) { /* If the requested length is at least as large as the buffer, and if there is no mark/reset activity, and if line feeds are not being skipped, do not bother to copy the characters into the local buffer. In this way buffered streams will cascade harmlessly. */ if (len >= cb.length && markedChar <= UNMARKED && !skipLF) { return in.read(cbuf, off, len); } fill(); } if (nextChar >= nChars) return -1; if (skipLF) { skipLF = false; if (cb[nextChar] == '\n') { nextChar++; if (nextChar >= nChars) fill(); if (nextChar >= nChars) return -1; } } int n = Math.min(len, nChars - nextChar); System.arraycopy(cb, nextChar, cbuf, off, n); nextChar += n; return n; }

The following function ensures that a subset of a character array can be read more safely

public int read(char cbuf[], int off, int len) throws IOException { synchronized (lock) { ensureOpen(); if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int n = read1(cbuf, off, len); if (n <= 0) return n; while ((n < len) && in.ready()) { int n1 = read1(cbuf, off + n, len - n); if (n1 <= 0) break; n += n1; } return n; } }

The following function reads a line of elements

String readLine(boolean ignoreLF) throws IOException { StringBuffer s = null; int startChar; synchronized (lock) { ensureOpen(); boolean omitLF = ignoreLF || skipLF; bufferLoop: for (;;) { if (nextChar >= nChars) fill(); if (nextChar >= nChars) { /* EOF */ if (s != null && s.length() > 0) return s.toString(); else return null; } boolean eol = false; char c = 0; int i; /* Skip a leftover '\n', if necessary */ if (omitLF && (cb[nextChar] == '\n')) nextChar++; skipLF = false; omitLF = false; charLoop: for (i = nextChar; i < nChars; i++) { c = cb[i]; if ((c == '\n') || (c == '\r')) { eol = true; break charLoop; } } startChar = nextChar; nextChar = i; if (eol) { String str; if (s == null) { str = new String(cb, startChar, i - startChar); } else { s.append(cb, startChar, i - startChar); str = s.toString(); } nextChar++; if (c == '\r') { skipLF = true; } return str; } if (s == null) s = new StringBuffer(defaultExpectedLineLength); s.append(cb, startChar, i - startChar); } } }

Read a row of elements

public String readLine() throws IOException { return readLine(false); }

Skipping characters

public long skip(long n) throws IOException { if (n < 0L) { throw new IllegalArgumentException("skip value is negative"); } synchronized (lock) { ensureOpen(); long r = n; while (r > 0) { if (nextChar >= nChars) fill(); if (nextChar >= nChars) /* EOF */ break; if (skipLF) { skipLF = false; if (cb[nextChar] == '\n') { nextChar++; } } long d = nChars - nextChar; if (r <= d) { nextChar += r; r = 0; break; } else { r -= d; nextChar = nChars; } } return n - r; } }

Determine whether the file is ready for reading

public boolean ready() throws IOException { synchronized (lock) { ensureOpen(); /* * If newline needs to be skipped and the next char to be read * is a newline character, then just skip it right away. */ if (skipLF) { /* Note that in.ready() will return true if and only if the next * read on the stream will not block. */ if (nextChar >= nChars && in.ready()) { fill(); } if (nextChar < nChars) { if (cb[nextChar] == '\n') nextChar++; skipLF = false; } } return (nextChar < nChars) || in.ready(); } }

The following defines the method to support tags

public boolean markSupported() { return true; }

The tag bits are defined below

public void mark(int readAheadLimit) throws IOException { if (readAheadLimit < 0) { throw new IllegalArgumentException("Read-ahead limit < 0"); } synchronized (lock) { ensureOpen(); this.readAheadLimit = readAheadLimit; markedChar = nextChar; markedSkipLF = skipLF; } }

The following function defines the reset method

public void reset() throws IOException { synchronized (lock) { ensureOpen(); if (markedChar < 0) throw new IOException((markedChar == INVALIDATED) ? "Mark invalid" : "Stream not marked"); nextChar = markedChar; skipLF = markedSkipLF; } }

The following function defines the closing of the buffer stream

public void close() throws IOException { synchronized (lock) { if (in == null) return; try { in.close(); } finally { in = null; cb = null; } } }

Returns a Stream whose elements are rows read from this BufferedReader.

public Stream<String> lines() { Iterator<String> iter = new Iterator<String>() { String nextLine = null; @Override public boolean hasNext() { if (nextLine != null) { return true; } else { try { nextLine = readLine(); return (nextLine != null); } catch (IOException e) { throw new UncheckedIOException(e); } } } @Override public String next() { if (nextLine != null || hasNext()) { String line = nextLine; nextLine = null; return line; } else { throw new NoSuchElementException(); } } }; return StreamSupport.stream(Spliterators.spliteratorUnknownSize( iter, Spliterator.ORDERED | Spliterator.NONNULL), false); }

3, BufferedWriter function source code introduction

BufferedWriter inherits from the Writer class

public class BufferedWriter extends Writer { }

Define an output standard bit

private Writer out;

The following defines the char array and its subsequent flag bits

private char cb[]; private int nChars, nextChar;

A default buffer length of 8k is defined

private static int defaultCharBufferSize = 8192;

A row separator attribute is defined below

private String lineSeparator;

Create a buffered character output stream using an output buffer of the default size.

public BufferedWriter(Writer out) { this(out, defaultCharBufferSize); }

Create a buffer reader

public BufferedWriter(Writer out, int sz) { super(out); if (sz <= 0) throw new IllegalArgumentException("Buffer size <= 0"); this.out = out; cb = new char[sz]; nChars = sz; nextChar = 0; lineSeparator = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("line.separator")); }

Used to ensure that the file is open

private void ensureOpen() throws IOException { if (out == null) throw new IOException("Stream closed"); }

Define buffer flush

void flushBuffer() throws IOException { synchronized (lock) { ensureOpen(); if (nextChar == 0) return; out.write(cb, 0, nextChar); nextChar = 0; } }

Write a single byte

public void write(int c) throws IOException { synchronized (lock) { ensureOpen(); if (nextChar >= nChars) flushBuffer(); cb[nextChar++] = (char) c; } }

Take the minimum value

private int min(int a, int b) { if (a < b) return a; return b; }

Reads a subset of the char array

public void write(char cbuf[], int off, int len) throws IOException { synchronized (lock) { ensureOpen(); if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } if (len >= nChars) { /* If the request length exceeds the size of the output buffer, flush the buffer and then write the data directly. In this way buffered streams will cascade harmlessly. */ flushBuffer(); out.write(cbuf, off, len); return; } int b = off, t = off + len; while (b < t) { int d = min(nChars - nextChar, t - b); System.arraycopy(cbuf, b, cb, nextChar, d); b += d; nextChar += d; if (nextChar >= nChars) flushBuffer(); } } }

Safe write char array

public void write(String s, int off, int len) throws IOException { synchronized (lock) { ensureOpen(); int b = off, t = off + len; while (b < t) { int d = min(nChars - nextChar, t - b); s.getChars(b, b + d, cb, nextChar); b += d; nextChar += d; if (nextChar >= nChars) flushBuffer(); } } }

Create a new row

public void newLine() throws IOException { write(lineSeparator); }

Define refresh function

public void flush() throws IOException { synchronized (lock) { flushBuffer(); out.flush(); } }

Define buffer write stream function

public void close() throws IOException { synchronized (lock) { if (out == null) { return; } try (Writer w = out) { flushBuffer(); } finally { out = null; cb = null; } } }

17 November 2021, 20:23 | Views: 8066

Add new comment

For adding a comment, please log in
or create account

0 comments