首页 > 代码库 > BufferedReader源码分析之readLine方法

BufferedReader源码分析之readLine方法

readLine方法是BufferedReader中一个非常常用的方法

使用它我们可以从一段输入流中一行一行的读数据

行的区分用"\r","\n"或者是"\r\n",下面就是BufferedReader中readLine的源代码

详细的分析都写在注释里了

	String readLine(boolean ignoreLF) throws IOException {
		StringBuffer s = null;
		int startChar;

		synchronized (lock) {
			// 确保底层的inputStream未被关闭
			ensureOpen();
			// ignoreLF在BufferedReader中始终为false
			// 而skipLF则会在读到"\r"字符之后被设置为true,通过这样来忽略掉之后的"\n"
			boolean omitLF = ignoreLF || skipLF;
			// 接下来是两个循环,第一层bufferLoop主要是用来往底层的数组里填充字符,这个底层数组就相当于一个缓冲区
			// 而这个缓冲区的大小可以通过BufferedReader(Reader in, int
			// sz)这个构造方法的第二个参数来指定,默认为8192bytes
			// 而charLoop则是用来遍历底层数组,每次读完底层数组里的数据,就把这些数据写到一个StringBuffer里,
			// 直到读到"\r"或"\n"的时候,写入最后一批数据之后就返回结果并退出整个循环
			bufferLoop: for (;;) {
				// nextChar表示下一个要读的字符的位置、nChars=从inputstream中读入的字符数+nextChar
				if (nextChar >= nChars)
					fill();
				// 读到了inputstream的末尾
				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;

				// 退出这一层循环有两种情况:1、读到"\r"或者"\n" 2、底层数组cb被读完了
				charLoop: for (i = nextChar; i < nChars; i++) {
					c = cb[i];
					if ((c == '\n') || (c == '\r')) {
						eol = true;
						break charLoop;
					}
				}

				// 读取底层数组的开始位置
				startChar = nextChar;
				// 当前读取到的位置
				nextChar = i;

				// 是否读完了一行(end of line)
				if (eol) {
					String str;
					if (s == null) {
						// 这里直接用s不就行了吗。为什么要搞个str变量
						str = new String(cb, startChar, i - startChar);
					} else {
						s.append(cb, startChar, i - startChar);
						str = s.toString();
					}
					// 下一次要读取的位置
					nextChar++;
					// 下一次若读到"\n"则会忽略掉,而不会终止读
					if (c == '\r') {
						skipLF = true;
					}
					return str;
				}

				// 写入读到的数据
				if (s == null)
					s = new StringBuffer(defaultExpectedLineLength);
				s.append(cb, startChar, i - startChar);
			}
		}
	}