بالنظر إلى إدخال java ، كيف يمكنني تحديد الإزاحة الحالية في الدفق؟

StackOverflow https://stackoverflow.com/questions/240294

  •  04-07-2019
  •  | 
  •  

سؤال

أود شيئًا مثل عام وقابل للاستخدام getPosition() الطريقة التي ستخبرني عدد البايتات التي تقرأ من نقطة انطلاق الدفق. من الناحية المثالية ، أفضل أن يعمل هذا مع جميع المدخلات ، حتى لا أضطر إلى لف كل واحد منهم وأنا أحصل عليها من مصادر متباينة.

هل يوجد مثل هذا الوحش؟ إذا لم يكن الأمر كذلك ، هل يمكن لأي شخص أن يوصي بتنفيذ حالي لعد InputStream?

هل كانت مفيدة؟

المحلول

ألق نظرة على CountingInputStream في حزمة العموم IO. لديهم مجموعة جيدة جدا من المتغيرات الإدخال الأخرى المفيدة كذلك.

نصائح أخرى

ستحتاج إلى متابعة نمط الديكور الذي تم إنشاؤه في java.io لتنفيذ هذا.

لنجربها هنا:

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

}

تهدف inputstreams إلى أن تكون آمنة لخيط الخيط ، بحيث يفسر الاستخدام الليبرالي للمزامنة. لقد لعبت مع volatile و AtomicLong متغيرات الموضع ، ولكن التزامن ربما يكون الأفضل لأنه يسمح لخيط واحد بالعمل على الدفق والاستعلام عن موضعه دون التخلي عن القفل.

PositionInputStream is = …
synchronized (is) {
  is.read(buf);
  pos = is.getPosition();
}

رقم. InputStream يهدف إلى التعامل مع كميات لا حصر لها من البيانات ، وبالتالي فإن العداد سوف يعترض الطريق. بالإضافة إلى لفهم جميعًا ، قد تتمكن من فعل شيء ما مع الجوانب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top