Read-ahead four bytes and check for BOM marks. <br>
Extra bytes are unread back to the stream, only BOM bytes are skipped.
@throws IOException 读取引起的异常
164672
protected void init() throws IOException {
		if (isInited) {
			return;
		}

		byte bom[] = new byte[BOM_SIZE];
		int n, unread;
		n = in.read(bom, 0, bom.length);

		if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
			charset = "UTF-32BE";
			unread = n - 4;
		} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
			charset = "UTF-32LE";
			unread = n - 4;
		} else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
			charset = "UTF-8";
			unread = n - 3;
		} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
			charset = "UTF-16BE";
			unread = n - 2;
		} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
			charset = "UTF-16LE";
			unread = n - 2;
		} else {
			// Unicode BOM mark not found, unread all bytes
			charset = defaultCharset;
			unread = n;
		}
		// System.out.println("read=" + n + ", unread=" + unread);

		if (unread > 0) {
			in.unread(bom, (n - unread), unread);
		}

		isInited = true;
	}
832301
protected boolean readChunk ()
        throws IOException
    {
        int offset = _sync.buffer(BUFFER_SIZE);
        int bytes = _in.read(_sync.data, offset, BUFFER_SIZE);
        if (bytes > 0) {
            _sync.wrote(bytes);
            return true;
        }
        return false;
    }
1051797
protected void init() throws IOException {
		if (internalIn2 != null) return;

		String encoding;
		byte bom[] = new byte[BOM_SIZE];
		int n, unread;
		n = internalIn.read(bom, 0, bom.length);

		if ( (bom[0] == (byte)0x00) && (bom[1] == (byte)0x00) &&
				(bom[2] == (byte)0xFE) && (bom[3] == (byte)0xFF) ) {
			encoding = "UTF-32BE";
			unread = n - 4;
		} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) &&
				(bom[2] == (byte)0x00) && (bom[3] == (byte)0x00) ) {
			encoding = "UTF-32LE";
			unread = n - 4;
		} else if (  (bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB) &&
				(bom[2] == (byte)0xBF) ) {
			encoding = "UTF-8";
			unread = n - 3;
		} else if ( (bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF) ) {
			encoding = "UTF-16BE";
			unread = n - 2;
		} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) ) {
			encoding = "UTF-16LE";
			unread = n - 2;
		} else {
			// Unicode BOM not found, unread all bytes
			encoding = defaultEnc;
			unread = n;
		}

		if (unread > 0) internalIn.unread(bom, (n - unread), unread);

		// Use given encoding
		if (encoding == null) {
			internalIn2 = new InputStreamReader(internalIn);
		} else if (strict) {
			internalIn2 = new InputStreamReader(internalIn, Charset.forName(encoding).newDecoder());
		} else {
			internalIn2 = new InputStreamReader(internalIn, encoding);
		}
	}
899033
@Override
	public long skip(long n) throws IOException {
		if (defaultSkip) {
			// use skip method of parent stream
			// may not work if skip not implemented by parent
			long bs = super.skip(n);
			bytesRead += bs;

			return bs;
		}

		if (n <= 0) {
			return 0;
		}

		long left = n;
		byte[] sBuff = new byte[SKIP_BUFFER_SIZE];

		while (left > 0) {
			int res = read(sBuff, 0, (int) (left < SKIP_BUFFER_SIZE ? left : SKIP_BUFFER_SIZE));
			if (res < 0) {
				break;
			}
			left -= res;
		}

		return n - left;
	}
549437
public boolean skipPreamble()
            throws IOException {
        // First delimiter may be not preceeded with a CRLF.
        System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);
        boundaryLength = boundary.length - 2;
        try {
            // Discard all data up to the delimiter.
            discardBodyData();

            // Read boundary - if succeded, the stream contains an
            // encapsulation.
            return readBoundary();
        } catch (MalformedStreamException e) {
            return false;
        } finally {
            // Restore delimiter.
            System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2);
            boundaryLength = boundary.length;
            boundary[0] = CR;
            boundary[1] = LF;
        }
    }
880564
private byte[] readBytes()
        throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int c;
        boolean cr=false;
        boolean lf=false;
        
        // loop for all lines`
        while (true)
        {
            int b=0;
            while ((c=(_char!=-2)?_char:_in.read())!=-1)
            {
                _char=-2;

                // look for CR and/or LF
                if (c==13 || c==10)
                {
                    if (c==13) _char=_in.read();
                    break;
                }

                // look for boundary
                if (b>=0 && b<_byteBoundary.length && c==_byteBoundary[b])
                    b++;
                else
                {
                    // this is not a boundary
                    if (cr) baos.write(13);
                    if (lf) baos.write(10);
                    cr=lf=false;
                    
                    if (b>0)
                        baos.write(_byteBoundary,0,b);
                    b=-1;
                  
                    baos.write(c);
                }
            }

            // check partial boundary
            if ((b>0 && b<_byteBoundary.length-2) ||
                (b==_byteBoundary.length-1))
            {
                if (cr) baos.write(13);
                if (lf) baos.write(10);
                cr=lf=false;
                baos.write(_byteBoundary,0,b);
                b=-1;
            }
            
            // boundary match
            if (b>0 || c==-1)
            {
                if (b==_byteBoundary.length)
                    _lastPart=true;
                if (_char==10) _char=-2;
                break;
            }
            
            // handle CR LF
            if (cr) baos.write(13);
            if (lf) baos.write(10);
            cr=(c==13);
            lf=(c==10 || _char==10);
            if (_char==10) _char=-2;  
        }
        if(log.isTraceEnabled())log.trace(baos.toString());
        return baos.toByteArray();
    }
644964
private void readBOM() throws EOFException {
        int readerIndex = content.readerIndex();
        int lastBOMIndex = content.forEachByte(bomProcessor);

        if (lastBOMIndex == -1) {
            throw NEED_MORE_DATA;
        }
        if (lastBOMIndex > readerIndex) {
            this.content.skipBytes(lastBOMIndex - readerIndex + 1);
            this.content.discardReadBytes();
        }

        this.levelStack.pop();
    }
890832
public boolean skipPreamble () throws IOException
  {
    // First delimiter may be not preceeded with a CRLF.
    System.arraycopy (m_aBoundary, 2, m_aBoundary, 0, m_aBoundary.length - 2);
    m_nBoundaryLength = m_aBoundary.length - 2;
    try
    {
      // Discard all data up to the delimiter.
      discardBodyData ();

      // Read boundary - if succeded, the stream contains an
      // encapsulation.
      return readBoundary ();
    }
    catch (final MultipartMalformedStreamException e)
    {
      return false;
    }
    finally
    {
      // Restore delimiter.
      System.arraycopy (m_aBoundary, 0, m_aBoundary, 2, m_aBoundary.length - 2);
      m_nBoundaryLength = m_aBoundary.length;
      m_aBoundary[0] = CR;
      m_aBoundary[1] = LF;
    }
  }
962106
public int readFrom(InputStream stream) throws IOException {
        int bytesRead = stream.read(buffer);
        if (bytesRead < 0) {
            bytesInBuffer = 0;
        } else {
            bytesInBuffer = bytesRead;
        }
        return bytesRead;
    }
744130
@Override
  public int read () throws IOException
  {
    _ensureOpen ();
    while (true)
    {
      if (m_nNextCharIndex >= m_nChars)
      {
        _fill ();
        if (m_nNextCharIndex >= m_nChars)
          return -1;
      }
      if (m_bSkipLF)
      {
        m_bSkipLF = false;
        if (m_aBuf[m_nNextCharIndex] == '\n')
        {
          m_nNextCharIndex++;
          continue;
        }
      }
      return m_aBuf[m_nNextCharIndex++];
    }
  }
557852
private void readMoreBytesFromStream() throws IOException {
        if (!innerStreamHasMoreData) {
            return;
        }

        int bufferSpaceAvailable = buffer.length - bytesInBuffer;
        if (bufferSpaceAvailable <= 0) {
            return;
        }

        int bytesRead =
                stream.read(buffer, bytesInBuffer, bufferSpaceAvailable);

        if (bytesRead == -1) {
            innerStreamHasMoreData = false;
        } else {
            bytesInBuffer += bytesRead;
        }
    }
861361
public byte readByte() throws IOException {

		// buffer depleted ?
		if (head == tail) {
			head = 0;
			// Refill.
			tail = input.read(buffer, head, bufSize);
			if (tail == -1) {
				// no more data available.
				throw new IOException("No more data is available");
			}
		}

		return buffer[head++];
	}
629316
private void nextChunk() throws IOException {
        if (!this.bof) {
            this.readCrlf();
        }
        this.size = ChunkedInputStream.chunkSize(this.origin);
        this.bof = false;
        this.pos = 0;
        if (this.size == 0) {
            this.eof = true;
        }
    }
191898
private static String readLineFromReaderWithMark(final Reader input)
            throws IOException {
        char[] cbuf = new char[charBufferSize];
        try {
            input.mark(charBufferSize);
        } catch (IOException e) {
            // this should never happen
            LOG.warning("Caught exception setting mark on supporting reader: " + e);
            // fallback
            return readLineFromReaderWithoutMark(input);
        }

        // could be changed into do..while, but then
        // we might create an additional StringBuilder
        // instance at the end of the stream
        int count = input.read(cbuf);
        if (count == EOF) // we are at the end of the input data
            return null;

        StringBuilder line = new StringBuilder(expectedLineLength);
        // now work on the buffer(s)
        int ls = lineSeparatorIndex(cbuf, count);
        while (ls == -1) {
            line.append(cbuf, 0, count);
            count = input.read(cbuf);
            if (count == EOF) {
                // we are at the end of the input data
                return line.toString();
            }
            ls = lineSeparatorIndex(cbuf, count);
        }
        line.append(cbuf, 0, ls);

        // correct ls if we have \r\n
        int skipLS = 1;
        if (ls + 1 < count) {
            // we are not at the end of the buffer
            if (cbuf[ls] == '\r' && cbuf[ls + 1] == '\n') {
                skipLS++;
            }
        } else {
            if (cbuf[ls] == '\r' && input.read() == '\n') {
                skipLS++;
            }
        }

        //reset() and skip over last linesep
        input.reset();
        input.skip(line.length() + skipLS);
        return line.toString();
    }
1011012
@Override
  public int read() throws IOException {
    if (mPosition == mLength) { // at end of file
      return -1;
    }
    CountingRetry retry = new CountingRetry(mBlockWorkerClientReadRetry);
    IOException lastException = null;
    while (retry.attempt()) {
      try {
        updateStream();
        int result = mBlockInStream.read();
        if (result != -1) {
          mPosition++;
        }
        return result;
      } catch (UnavailableException | DeadlineExceededException | ConnectException e) {
        lastException = e;
        if (mBlockInStream != null) {
          handleRetryableException(mBlockInStream, e);
          mBlockInStream = null;
        }
      }
    }
    throw lastException;
  }
670436
public int read() throws IOException {
		if (leftover != null && leftover.remaining() > 0) {
			int b = leftover.get();
			if (leftover.remaining() == 0) {
				leftover = null;
			}
			return b;
		}
		return input.read();
	}
600412
protected function readLine()
    {
        if ($this->line_number === 0)
        {
            $st = ftell($this->file_handle);
            if ($st === 0)
            { 
                // Attempt to read a Byte Order Mark only if this file handle is at the start of the file
                $utf8_bom = Encoding::getBOM('UTF8');
                $maybe_bom = fread($this->file_handle, 3);
                $this->has_bom = $utf8_bom === $maybe_bom;

                // Rewind if the first three characters are not the UTF8 BOM
                if (!$this->has_bom)
                    fseek($this->file_handle, 0);
            }
        }

        if ($this->read_header && empty($this->line_number) && $this->header === null)
            $this->header = fgetcsv($this->file_handle, 0, $this->delimiter, $this->enclosure, $this->escape_char);

        $line = fgetcsv($this->file_handle, 0, $this->delimiter, $this->enclosure, $this->escape_char);

        if ($line === false)
        {
            $this->current_line = false;
            return;
        }

        if ($this->header !== null)
        {
            $row = array();
            foreach ($line as $idx => $col)
            {
                $name = isset($this->header[$idx]) ? $this->header[$idx] : null;
                if ($name)
                    $row[$name] = $col;
                else
                    $row[] = $col;
            }
            $this->current_line = $row;
        }
        else
            $this->current_line = $line;
    }