Reading a file at a certain speed in Java

Is there an article / algorithm, how can I read a long file at a certain speed?

Say I donโ€™t want to transfer 10 kb / s when issuing reads.

+5
source share
6 answers

The rough solution is to just read a piece at a time, and then sleep, for example, 10k, and then sleep a second. But the first question I must ask is why? There are several likely answers:

  • You do not want to create work faster than you can do; or
  • You do not want to put too much stress on the system.

- . . . Java concurrency . .

. .., .

- ArrayBlockingQueue , (1), (2). , , . () , , (2).

+4

, ThrottledInputStream.

:

        final InputStream slowIS = new ThrottledInputStream(new BufferedInputStream(new FileInputStream("c:\\file.txt"),8000),300);

300 - . 8000 - BufferedInputStream.

, , read (byte b [], int off, int len), System.currentTimeMillis(). System.currentTimeMillis() , . , System.currentTimeMillis().

BufferedInputStream , FileInputStream , . CPU 10%. .

import java.io.InputStream;
import java.io.IOException;

public class ThrottledInputStream extends InputStream {
    private final InputStream rawStream;
    private long totalBytesRead;
    private long startTimeMillis;

    private static final int BYTES_PER_KILOBYTE = 1024;
    private static final int MILLIS_PER_SECOND = 1000;
    private final int ratePerMillis;

    public ThrottledInputStream(InputStream rawStream, int kBytesPersecond) {
        this.rawStream = rawStream;
        ratePerMillis = kBytesPersecond * BYTES_PER_KILOBYTE / MILLIS_PER_SECOND;
    }

    @Override
    public int read() throws IOException {
        if (startTimeMillis == 0) {
            startTimeMillis = System.currentTimeMillis();
        }
        long now = System.currentTimeMillis();
        long interval = now - startTimeMillis;
        //see if we are too fast..
        if (interval * ratePerMillis < totalBytesRead + 1) { //+1 because we are reading 1 byte
            try {
                final long sleepTime = ratePerMillis / (totalBytesRead + 1) - interval; // will most likely only be relevant on the first few passes
                Thread.sleep(Math.max(1, sleepTime));
            } catch (InterruptedException e) {//never realized what that is good for :)
            }
        }
        totalBytesRead += 1;
        return rawStream.read();
    }
}
+12
  • while! EOF
    • System.currentTimeMillis() + 1000 (1 )
    • 10K
    • ,
      • , Thread.sleep() -

ThrottledInputStream, InputStream, , .

+4

, " " " ".

" ", , :

 while not EOF do
    read a buffer
    Thread.wait(time)
    write the buffer
 od

- ; 10K , .

, , , .

, - , , , โ€‹โ€‹ , ; . , , .., , , .

+1

Java I/O, . InputStream, InputStream . ( FileInputStream, .)

. , , (System.nanoTime). , , wait, . , ( , 0, ).

+1

RateLimiter. InputStream. .

public class InputStreamFlow extends InputStream {
    private final InputStream inputStream;
    private final RateLimiter maxBytesPerSecond;

    public InputStreamFlow(InputStream inputStream, RateLimiter limiter) {
        this.inputStream = inputStream;
        this.maxBytesPerSecond = limiter;
    }

    @Override
    public int read() throws IOException {
        maxBytesPerSecond.acquire(1);
        return (inputStream.read());
    }

    @Override
    public int read(byte[] b) throws IOException {
        maxBytesPerSecond.acquire(b.length);
        return (inputStream.read(b));
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        maxBytesPerSecond.acquire(len);
        return (inputStream.read(b,off, len));
    }
}

1 /, :

final RateLimiter limiter = RateLimiter.create(RateLimiter.ONE_MB); 
final InputStreamFlow inputStreamFlow = new InputStreamFlow(originalInputStream, limiter);
0
source

All Articles