Frage

Sollte ziemlich einfach sein: Ich habe einen Inputstream, wo ich spähen will (nicht gelesen) die ersten zwei Bytes, das heißt ich mag die „aktuelle Position“ des Input bei 0 nach meinem späht seinen stil. Was ist die beste und sicherste Weg, dies zu tun?

Antwort - Wie ich vermutet hatte, die Lösung in einem BufferedInputStream zu wickeln war die Markierbarkeit bietet. Dank Rasmus.

War es hilfreich?

Lösung

Für eine allgemeine Input, würde ich es in einem BufferedInputStream wickeln und etwas tun, wie folgt aus:

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

Andere Tipps

Wenn ein BufferedInputStream sich immer vergewissern, dass die input nicht bereits gepuffert, wird das doppelte Pufferung einige ernsthaft hart verursachen Fehler zu finden. Darüber hinaus müssen Sie Leser anders zu handhaben, die Umwandlung in eine Stream und Buffering verursacht Bytes verloren, wenn der Reader Buffered wird. Auch wenn Sie einen Reader verwenden erinnern, dass Sie nicht Bytes, sondern Zeichen in der Standardcodierung lesen (es sei denn, eine explizite Codierung festgelegt wurde). Ein Beispiel für einen gepufferten Eingabestream, die Sie vielleicht nicht wissen, ist URL url; url.openStream ();

Ich habe keine Referenzen für diese Informationen, es kommt von Code debuggen. Der Haupt Fall, in dem das Thema für mich aufgetreten war in Code, der aus einer Datei in einen komprimierten Stream lesen. Wenn ich mich richtig erinnere, sobald Sie das Debuggen durch den Code gibt es Kommentare in der Java-Quelle beginnen, dass bestimmte Dinge nicht richtig funktionieren immer. Ich erinnere mich nicht, wo die Informationen aus mit BufferedReader und BufferedInputStream  kommt aus aber ich denke, dass sofort auf selbst die einfachsten Test nicht bestanden. Denken Sie daran, diese Sie testen müssen mehr als die Puffergröße zu Markierung (die für BufferedReader gegen BufferedInputStream unterschiedlich ist), treten die Probleme auf, wenn die Bytes das Ende des Puffers erreichen gelesen werden. Hinweis: Es gibt eine Quellcode-Puffergröße ist, die auf die Puffergröße unterschiedlich sein können Sie im Konstruktor festgelegt. Es ist eine Weile her, seit ich habe dies so meine Erinnerungen an Details ein wenig aus sein kann. Tests durchgeführt wurden mit einem Filterreader / Filterinput, fügen Sie einen den direkten Strom und eine mit dem gepufferten Strom den Unterschied zu sehen.

Ich fand eine Implementierung eines PeekableInputStream hier:

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

Die Idee der Implementierung in dem Artikel dargestellt ist, dass es eine Reihe von „guckte“ Wert intern hält. Wenn Sie lesen aufrufen, werden die Werte zuerst aus dem peeked Array zurückgegeben, dann aus dem Eingangsstrom. Wenn Sie peek aufrufen, werden die Werte gelesen und in dem „guckte“ Array gespeichert.

Wie die Lizenz des Beispielcodes LGPL ist, kann es zu diesem Beitrag angehängt werden:

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;
  }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top