String readLine(boolean ignoreLF) throws IOException {
//行(hang)数据的缓冲s
StringBuffer s = null;
int startChar;
synchronized (lock) {
/*确保被bufferedReader包装的输入流没有关闭*/
ensureOpen();
/* 如果 读到'\r',skipLF置为true,
* 这是skip()方法里面的部分代码,它展示了通过skipLF来忽略'\n'
* if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
}
}
*ignoreLF一直就是false
**/
boolean omitLF = ignoreLF || skipLF;
/* bufferLoop主要是不断地遍历底层的数组cb,并取两个换行符之间的数据付给行缓冲s。当底层数组遍历完要用fill()把数据从流中填充到cb,直到流的末尾
*charloop,主要是遍历缓冲数组cb,以确定'\n','\r'的位置
nextChar:下次读取缓冲字符数组cb的位置,
nChars:缓冲字符数组cb的length
*/
bufferLoop:
for (;;) {
//1、如果缓冲数组的数据不足,或者已经读到了数组的末尾时:
//1.1如果下次读取的位置已经到了or超过数组的长度,从流中读数据到缓冲数组cb中
if (nextChar >= nChars)
fill();
/*1.2如果从流中读数据到数组cb之后, nextChar,nChars的大小关系没有改变.
说明到了文件的末尾,END OF FILE.返回s
*/
if (nextChar >= nChars) { /* EOF */
if (s != null && s.length() > 0)
return s.toString();
else
return null;
}
//2 缓冲数组中有足够的数据时:
/*从本个换行符所在的索引位置开始,遍历char [] cb ,直到找到\n \r,把两个换行符之间的字符序列填充进s
*eol:END OF LINE
*类属性char [] cb ,也就是bufferReader类的缓冲数组。length由构造器指定,若不指定默认为8 * 1024 = 8192,与内存页大小密切相关
* */
boolean eol = false;
char c = 0;
int i;
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;
}
}
/*2.1找到换行符后,从上个换行符到本换行符之间的序列,填充给s*/
startChar = nextChar;
nextChar = i;
if (eol) {
String str;
/*2.1.1如果是第一次遍历到换行符,*/
if (s == null)
{
str = new String(cb, startChar, i - startChar);
}
/*2.1.2至少遍历到一次换行符时*/
else
{
s.append(cb, startChar, i - startChar);
str = s.toString();
}
//更新下次读取的位置
nextChar++;
if (c == '\r') {
skipLF = true;
}
return str;
}
//2.2如果没有换行符
if (s == null)
//类属性int defaultExpectedLineLength = 80
s = new StringBuffer(defaultExpectedLineLength);
//填充s,从上个换行符到最后
s.append(cb, startChar, i - startChar);
}
}
}