문제

매우 간단해야합니다. 처음 두 바이트를 들여다보고 싶은 입력 스트림이 있습니다. 즉, 입력 스트림의 "현재 위치"가 엿보기 후 0이되기를 원합니다. 이 작업을 수행하는 가장 안전하고 가장 안전한 방법은 무엇입니까?

대답 - 내가 의심했듯이, 해결책은 그것을 포장성을 제공하는 BufferedInputStream으로 래핑하는 것이 었습니다. 감사합니다 Rasmus.

도움이 되었습니까?

해결책

일반적인 입력 스트림의 경우 BufferedInputStream으로 마무리하고 다음과 같은 작업을 수행합니다.

BufferedInputStream bis = new BufferedInputStream(inputStream);
bis.mark(2);
int byte1 = bis.read();
int byte2 = bis.read();
bis.reset();
// note: you must continue using the BufferedInputStream instead of the inputStream

다른 팁

PushbackInputStream이 유용 할 수 있습니다.

http://docs.oracle.com/javase/6/docs/api/java/io/pushbackinputstream.html

BufferedInputStream을 사용하는 경우 InputStream이 아직 버퍼링되지 않았는지 확인하고 이중 버퍼링은 버그를 찾기가 심각하게 어려워집니다. 또한 독자를 다르게 처리해야합니다. 스트리트 리더로 변환하고 버퍼링을 사용하면 독자가 버퍼링되면 바이트가 손실됩니다. 또한 독자를 사용하는 경우 바이트를 읽는 것이 아니라 기본 인코딩의 문자를 읽고 있음을 기억하십시오 (명시 적 인코딩이 설정되지 않는 한). 버퍼 입력 스트림의 예는 URL URL입니다. url.openstream ();

이 정보에 대한 참조가 없으며 디버깅 코드에서 비롯됩니다. 문제가 발생한 주요 사례는 파일에서 압축 스트림으로 읽는 코드에있었습니다. 코드를 통해 디버깅을 시작하면 올바르게 기억되면 Java 소스에는 특정 사항이 항상 올바르게 작동하지 않는다는 주석이 있습니다. BufferedReader 및 BufferedInputStream 사용의 정보가 어디에서 왔는지 기억하지 못하지만 가장 간단한 테스트에서도 바로 실패한다고 생각합니다. 이를 테스트해야합니다. 버퍼 크기보다 더 많이 표시해야합니다 (버퍼드 리더 대 BufferedInputStream과 다름). 읽기중인 바이트가 버퍼의 끝에 도달 할 때 문제가 발생합니다. 참고 생성자에서 설정 한 버퍼 크기와 다른 소스 코드 버퍼 크기가 있습니다. 내가 이것을 한 지 오래되었으므로 세부 사항에 대한 나의 회상이 약간 벗어날 수 있습니다. FilterReader/FilterInputStream을 사용하여 테스트를 수행하고 직접 스트림에 하나를 추가하고 하나는 버퍼링 된 스트림에 추가하여 차이를 확인했습니다.

여기에서 PeekableInputStream의 구현을 찾았습니다.

http://www.heatonresearch.com/articles/147/page2.html

기사에 표시된 구현의 아이디어는 내부적으로 "엿보기"값을 유지한다는 것입니다. 읽기를 호출하면 값은 먼저 엿보기 배열에서 입력 스트림에서 반환됩니다. Peek을 호출하면 값이 "Peeked"배열에 읽고 저장됩니다.

샘플 코드의 라이센스가 LGPL 이므로이 게시물에 첨부 할 수 있습니다.

package com.heatonresearch.httprecipes.html;

import java.io.*;

/**
 * The Heaton Research Spider Copyright 2007 by Heaton
 * Research, Inc.
 * 
 * HTTP Programming Recipes for Java ISBN: 0-9773206-6-9
 * http://www.heatonresearch.com/articles/series/16/
 * 
 * PeekableInputStream: This is a special input stream that
 * allows the program to peek one or more characters ahead
 * in the file.
 * 
 * This class is released under the:
 * GNU Lesser General Public License (LGPL)
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * @author Jeff Heaton
 * @version 1.1
 */
public class PeekableInputStream extends InputStream
{

  /**
   * The underlying stream.
   */
  private InputStream stream;

  /**
   * Bytes that have been peeked at.
   */
  private byte peekBytes[];

  /**
   * How many bytes have been peeked at.
   */
  private int peekLength;

  /**
   * The constructor accepts an InputStream to setup the
   * object.
   * 
   * @param is
   *          The InputStream to parse.
   */
  public PeekableInputStream(InputStream is)
  {
    this.stream = is;
    this.peekBytes = new byte[10];
    this.peekLength = 0;
  }

  /**
   * Peek at the next character from the stream.
   * 
   * @return The next character.
   * @throws IOException
   *           If an I/O exception occurs.
   */
  public int peek() throws IOException
  {
    return peek(0);
  }

  /**
   * Peek at a specified depth.
   * 
   * @param depth
   *          The depth to check.
   * @return The character peeked at.
   * @throws IOException
   *           If an I/O exception occurs.
   */
  public int peek(int depth) throws IOException
  {
    // does the size of the peek buffer need to be extended?
    if (this.peekBytes.length <= depth)
    {
      byte temp[] = new byte[depth + 10];
      for (int i = 0; i < this.peekBytes.length; i++)
      {
        temp[i] = this.peekBytes[i];
      }
      this.peekBytes = temp;
    }

    // does more data need to be read?
    if (depth >= this.peekLength)
    {
      int offset = this.peekLength;
      int length = (depth - this.peekLength) + 1;
      int lengthRead = this.stream.read(this.peekBytes, offset, length);

      if (lengthRead == -1)
      {
        return -1;
      }

      this.peekLength = depth + 1;
    }

    return this.peekBytes[depth];
  }

  /*
   * Read a single byte from the stream. @throws IOException
   * If an I/O exception occurs. @return The character that
   * was read from the stream.
   */
  @Override
  public int read() throws IOException
  {
    if (this.peekLength == 0)
    {
      return this.stream.read();
    }

    int result = this.peekBytes[0];
    this.peekLength--;
    for (int i = 0; i < this.peekLength; i++)
    {
      this.peekBytes[i] = this.peekBytes[i + 1];
    }

    return result;
  }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top