Bei einem Java-Input, wie kann ich den Strom in der Strom-Offset bestimmen?
-
04-07-2019 - |
Frage
würde ich so etwas wie eine allgemeine, wiederverwendbare getPosition()
Methode mag, die mir die Anzahl der gelesenen Bytes von dem Ausgangspunkt des Stroms wird es zeigen. Im Idealfall würde ich es vorziehen, diese mit allen Inputstreams zu arbeiten, so dass ich auf jeden einzelnen von ihnen nicht wickeln, wie ich sie aus verschiedenen Quellen erhalten.
Ist ein solches Tier gibt es? Wenn nicht, kann jemand eine vorhandene Implementierung einer Zählung InputStream
empfehlen?
Lösung
Hier finden Sie aktuelle CountingInputStream in dem Commons IO-Paket. Sie haben eine ziemlich gute Sammlung von anderen nützlichen Inputvarianten als auch.
Andere Tipps
Sie müssen das Dekorierermuster in java.io
etabliert folgen, dies umzusetzen.
Lassen Sie uns es versuchen hier:
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public final class PositionInputStream
extends FilterInputStream
{
private long pos = 0;
private long mark = 0;
public PositionInputStream(InputStream in)
{
super(in);
}
/**
* <p>Get the stream position.</p>
*
* <p>Eventually, the position will roll over to a negative number.
* Reading 1 Tb per second, this would occur after approximately three
* months. Applications should account for this possibility in their
* design.</p>
*
* @return the current stream position.
*/
public synchronized long getPosition()
{
return pos;
}
@Override
public synchronized int read()
throws IOException
{
int b = super.read();
if (b >= 0)
pos += 1;
return b;
}
@Override
public synchronized int read(byte[] b, int off, int len)
throws IOException
{
int n = super.read(b, off, len);
if (n > 0)
pos += n;
return n;
}
@Override
public synchronized long skip(long skip)
throws IOException
{
long n = super.skip(skip);
if (n > 0)
pos += n;
return n;
}
@Override
public synchronized void mark(int readlimit)
{
super.mark(readlimit);
mark = pos;
}
@Override
public synchronized void reset()
throws IOException
{
/* A call to reset can still succeed if mark is not supported, but the
* resulting stream position is undefined, so it's not allowed here. */
if (!markSupported())
throw new IOException("Mark not supported.");
super.reset();
pos = mark;
}
}
Die Inputstreams sollen Fäden sicher sein, so dass Konten für die liberale Verwendung der Synchronisation. Ich spielte mit volatile
und AtomicLong
Positionsvariablen, aber Synchronisation ist wahrscheinlich am besten, weil es ein Thread erlaubt auf dem Strom zu betreiben und seine Position abfragen, ohne das Schloss zu verzichten.
PositionInputStream is = …
synchronized (is) {
is.read(buf);
pos = is.getPosition();
}
Nein. InputStream
soll potentiell unendliche Datenmengen zu handhaben, so ein Zähler in die Quere kommen würde. Zusätzlich sie alle zu wickeln, Sie könnten in der Lage sein, etwas mit Aspekten zu tun.
Es gibt auch CountingInputStream
in Guava .
Quelle: https: //github.com/google/guava/blob/master/guava/src/com/google/common/io/CountingInputStream.java