docs: private List<String> readLine() throws IORuntimeException {
  		final List<String> currentFields = new ArrayList<>(maxFieldCount > 0 ? maxFieldCount : DEFAULT_ROW_CAPACITY);
  
  		final StrBuilder localCurrentField = currentField;
  		final char[] localBuf = this.buf;
  		int localBufPos = bufPos;//当前位置
  		int localPreChar = preChar;//前一个特殊分界字符
  		int localCopyStart = copyStart;//拷贝起始位置
  		int copyLen = 0; //拷贝长度
  
  		while (true) {
  			if (bufLen == localBufPos) {
  				// 此Buffer读取结束，开始读取下一段
  
  				if (copyLen > 0) {
  					localCurrentField.append(localBuf, localCopyStart, copyLen);
  				}
  				try {
  					bufLen = reader.read(localBuf);
  				} catch (IOException e) {
  					throw new IORuntimeException(e);
  				}
  
  				if (bufLen < 0) {
  					// CSV读取结束
  					finished = true;
  
  					if (localPreChar == config.fieldSeparator || localCurrentField.hasContent()) {
  						//剩余部分作为一个字段
  						currentFields.add(localCurrentField.toStringAndReset());
  					}
  					break;
  				}
  
  				//重置
  				localCopyStart = localBufPos = copyLen = 0;
  			}
  
  			final char c = localBuf[localBufPos++];
  
  			if (inQuotes) {
  				//引号内，做为内容，直到引号结束
  				if (c == config.textDelimiter) {
  					// End of quoted text
  					inQuotes = false;
  				} else {
  					if ((c == CharUtil.CR || c == CharUtil.LF) && localPreChar != CharUtil.CR) {
  						lineNo++;
  					}
  				}
  				copyLen++;
  			} else {
  				if (c == config.fieldSeparator) {
  					//一个字段结束
  					if (copyLen > 0) {
  						localCurrentField.append(localBuf, localCopyStart, copyLen);
  						copyLen = 0;
  					}
  					currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
  					localCopyStart = localBufPos;
  				} else if (c == config.textDelimiter) {
  					// 引号开始
  					inQuotes = true;
  					copyLen++;
  				} else if (c == CharUtil.CR) {
  					if (copyLen > 0) {
  						localCurrentField.append(localBuf, localCopyStart, copyLen);
  					}
  					currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
  					localPreChar = c;
  					localCopyStart = localBufPos;
  					break;
  				} else if (c == CharUtil.LF) {
  					if (localPreChar != CharUtil.CR) {
  						if (copyLen > 0) {
  							localCurrentField.append(localBuf, localCopyStart, copyLen);
  						}
  						currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
  						localPreChar = c;
  						localCopyStart = localBufPos;
  						break;
  					}
  					localCopyStart = localBufPos;
  				} else {
  					copyLen++;
  				}
  			}
  
  			localPreChar = c;
  		}
  
  		// restore fields
  		bufPos = localBufPos;
  		preChar = localPreChar;
  		copyStart = localCopyStart;
  
  		return currentFields;
  	}