A FilterInputStream with a limited bandwith : FilterInputStream « File Input Output « Java






A FilterInputStream with a limited bandwith

    


import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/*********************************************
    Copyright (c) 2001 by Daniel Matuschek
*********************************************/


/**
 * A FilterInputStream with a limited bandwith
 *
 * This implements an filter for an existing input stream that allows
 * it to limit the read bandwidth. This can be useful for network
 * streams that should be limited to a specified bandwidth.
 *
 * @author <a href="mailto: daniel@matuschek.net">Daniel Matuschek</a>
 * @version $id$
 */
public class LimitedBandwidthStream 
  extends FilterInputStream {
  

  /** usable bandwidth in bytes/second **/
  private int bandwidth = 0;
  
  /** bandwidth limit will be calculated form the start time **/
  private boolean isReading = false;

  /** number of bytes read **/
  private int count = 0;

  /** check bandwidth every n bytes **/
  private static int CHECK_INTERVAL = 100;

  /** start time **/
  long starttime = 0;

  /** used time **/   
  long usedtime = 0;
  

  /**
   * initializes the LimitedBandWidth stream
   */
  public LimitedBandwidthStream (InputStream in, int bandwidth) 
    throws IOException
  {
    super(in);

    if (bandwidth > 0) {
      this.bandwidth=bandwidth;
    } else {
      this.bandwidth=0;
    }

    count = 0;
  }

  /**
   * Reads the next byte.
   *
   * Reads the next byte of data from this input stream. The value byte 
   * is returned as an int in the range 0 to 255. If no byte is available 
   * because the end of the stream has been reached, the value -1 is 
   * returned. This method blocks until input data is available, the end 
   * of the stream is detected, or an exception is thrown.   
   * If the bandwidth consumption exceeds the defined limit, read will block
   * until the bandwidth is in the limit again.
   *
   * @return the next byte from the stream or -1 if end-of-stream 
   */
  public int read() 
    throws IOException
  {
    long currentBandwidth;

    if (! isReading) {
      starttime = System.currentTimeMillis();
      isReading = true;
    }

    // do bandwidth check only if bandwidth
    if ((bandwidth > 0) &&
  ((count % CHECK_INTERVAL) == 0)) {
      do {
  usedtime = System.currentTimeMillis()-starttime;
  if (usedtime > 0) {
    currentBandwidth = (count*1000) / usedtime;
  } else {
    currentBandwidth = 0;
  }
  if (currentBandwidth > bandwidth) {
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {}
  } 
      } while (currentBandwidth > bandwidth);
    }

    count++;
    return super.read();
  }

  /**
   * Shortcut for read(b,0,b.length)
   *
   * @see #read(byte[], int, int)
   */
  public int read(byte[] b) throws IOException {
    return read(b, 0, b.length);
  }
  
  /**
   * Reads a block of bytes from the stream.
   *
   * If the bandwith is not limited, it simply used the 
   * read(byte[], int, int) method of the input stream, otherwise it
   * uses multiple read() request to enforce bandwith limitation (this
   * is easier to implement using byte reads).
   *
   * @return the number of bytes read or -1 at end of stream 
   */
  public int read(byte[] b, int off, int len) throws IOException {
    int mycount = 0;
    int current = 0;
    // limit bandwidth ?
    if (bandwidth > 0) {
      for (int i=off; i < off+len; i++) {
  current = read();
  if (current == -1) {
    return mycount;
  } else {
    b[i]=(byte)current;
    count++;
    mycount++;
  }
      }
      return mycount;
    } else {
      return in.read(b, off, len);
    }
  }
      
} // LimitedBandwidthStream

   
    
    
    
  








Related examples in the same category

1.introduce a protocol for reading arbitrary length data in a uniform way