写入具有容量限制的OutputStream [英] writing to OutputStream having capacity restriction

查看:157
本文介绍了写入具有容量限制的OutputStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跟随问题,我之前问过:我正在实现 ByteArrayOutputStream 具有容量限制。我的主要限制是可用内存量。因此,拥有这样的流 os


  1. 当我写的不只是说 1MB 到我需要停止的输出流。
    我不想抛出异常,而是将 os
    输出流的完整内容写入指定的其他输出流参数。

    OutputStream输出;
    os.writeTo(out);

    之后,从开始就继续写 os


  2. 为了防止出现上述1的情况,我更倾向于尽可能地消耗 os
    。我的意思是将数据从其中复制到 out 的512KB
    块中。
    可行吗?如果是的话,建议如何解决?也许有一个内置的类可以满足我的要求


编辑:写入 out 的字节数也受到限制。我最多可以写入1GB。如果我有更多的话,我需要创建其他输出流,以从 os 中耗尽。
写入os的过程。可以像那样。 500MB写在那里-我立即将其传输出去。几秒钟后,在那里写入了700MB-我只需要消耗500MB到 out ,将另外200MB消耗到其他输出流( out2 ),我将需要在这种情况下创建

解决方案

您要描述的是BufferedOutputStream,您可以像这样构造那:

  new BufferedOutputStream(out,512000)

第一个arg是您拥有的另一个输出流,第二个arg是BufferedOutputStream内部缓冲区的大小



编辑:



好的,起初我并不完全了解您的需求。您确实需要扩展OutputStream来实现这一点。这是示例代码:



这里是如何使用以下代码:

  public static void main(String [] args)引发IOException {
AtomicLong idx = new AtomicLong(0);
try(
OutputStream out = new OutputStreamMultiVolume(10,()-> new FileOutputStream(getNextFilename(idx)));
){

out.write ( 01234567890123456789012345678901234567890123456789 .getBytes( UTF-8));
}
}

私有静态文件getNextFilename(AtomicLong idx){
返回new File( sample.file。 + idx.incrementAndGet()+。文本文件);
}

OutputStreamMultiVolume的第一个构造函数arg是卷的最大大小。如果达到这个大小,我们将关闭当前的outputStream,并调用OutputStreamSupplier来获取下一个。



此处的示例代码将字符串写为 01234567890123456789012345678901234567890123456789 (5倍于0123456789)到名为 sample.file.idx.txt的文件,每次达到流出最大大小(即,您将获得5个文件)时,idx都会增加。 / p>

和类intself:

 公共类OutputStreamMultiVolume扩展OutputStream {

私有最终长整型maxBytePerVolume;
private long bytesInCurrentVolume = 0;
私人OutputStream输出;
private OutputStreamSupplier outputStreamSupplier;

静态接口OutputStreamSupplier {
OutputStream get()抛出IOException;
}

public OutputStreamMultiVolume(long maxBytePerOutput,OutputStreamSupplier outputStreamSupplier)抛出IOException {
this.outputStreamSupplier = outputStreamSupplier;
this.maxBytePerVolume = maxBytePerOutput;
this.out = outputStreamSupplier.get();
}

@Override
公共同步void write(byte []个字节)引发IOException {
final int missingBytesInVol =(int)(maxBytePerVolume-bytesInCurrentVolume);
if(remainingBytesInVol> = bytes.length){
out.write(bytes);
bytesInCurrentVolume + = bytes.length;
的回报;
}

out.write(bytes,0,missingBytesInVol);
switchOutput();

this.write(bytes,maintenantBytesInVol,bytes.length -maintenantBytesInVol);
}

@Override
公共同步void write(int b)引发IOException {
if(bytesInCurrentVolume + 1< = maxBytePerVolume){
out .write(b);
bytesInCurrentVolume + = 1;
的回报;
}

switchOutput();
out.write(b);
bytesInCurrentVolume + = 1;
}

@Override
公共同步void write(byte [] b,int off,int len)抛出IOException {
final int剩下的BytesInVol =(int)( maxBytePerVolume-bytesInCurrentVolume);
if(remainingBytesInVol> = len){
out.write(b,off,len);
bytesInCurrentVolume + = len;
的回报;
}

out.write(b,off,剩下的BytesInVol);
switchOutput();
this.write(b,off +剩下的BytesInVol,len-剩下的BytesInVol);
bytesInCurrentVolume + = len-剩下的BytesInVol;
}

private void switchOutput()引发IOException {
out.flush();
out.close();

out = outputStreamSupplier.get();
bytesInCurrentVolume = 0;
}

@Override
公共同步void close()引发IOException {
out.close();
}

@Override
公共同步void flush()引发IOException {
out.flush();
}
}


Following the question I asked before: I am implementing an ByteArrayOutputStream having capacity restriction. My main limitation is an amount of available memory. So having such stream os:

  1. When I write more than say 1MB to the output stream I need to "stop". I prefer not throw exception but write the complete contents of os output stream to the specified other output stream argument. OutputStream out; os.writeTo(out); And after that continue the writings to os from its beginning

  2. In order to prevent the situation described at 1. , I prefer to drain os, as freuqntely as possible. I mean copy the data from it to out in chuncks of 512KB Is it feasible? If yes any advices how can it be done? Or may be there is a built in class which answers my requirements

Edit: The amount of bytes written to out is also limited. I can write there up to 1GB. If I have more, I need to create other output stream in order to drain from os there. The proccess of writing to os. can be like that. 500MB was written there - I transfer it immidiately to out. After several seconds 700MB were written there - I need to drain only 500MB to out and other 200MB to other outputstream(out2), which I`ll need to create upon such situation

解决方案

What you are describing is a BufferedOutputStream, which you can construct like that :

new BufferedOutputStream(out, 512000)

The first arg is the other outputstream you have and the second one is the size of the BufferedOutputStream internal buffer

EDIT:

ok, i did not fully understand your need at first. You will indeed need to extend OutputStream to achieve that. Here is a sample code :

Here is how to use the below code :

    public static void main(String[] args) throws IOException {
        AtomicLong idx = new AtomicLong(0);
        try (
            OutputStream out = new OutputStreamMultiVolume(10, () -> new FileOutputStream(getNextFilename(idx)));
            ) {

            out.write("01234567890123456789012345678901234567890123456789".getBytes("UTF-8"));
        }
    }

    private static File getNextFilename(AtomicLong idx) {
        return new File("sample.file." + idx.incrementAndGet() + ".txt");
    }

The first constructor arg of OutputStreamMultiVolume is the max size of a volume. If we reach this size, we will close the current outputStream, and call the OutputStreamSupplier to get the next one.

The example code here will write the String 01234567890123456789012345678901234567890123456789 (5 times 0123456789) to files named 'sample.file.idx.txt' where idx is increased each time we reach the outstream max size (so you'll get 5 files).

and the class intself :

public class OutputStreamMultiVolume extends OutputStream {

    private final long maxBytePerVolume;
    private long bytesInCurrentVolume = 0;
    private OutputStream out;
    private OutputStreamSupplier outputStreamSupplier;

    static interface OutputStreamSupplier {
        OutputStream get() throws IOException;
    }

    public OutputStreamMultiVolume(long maxBytePerOutput, OutputStreamSupplier outputStreamSupplier) throws IOException {
        this.outputStreamSupplier = outputStreamSupplier;
        this.maxBytePerVolume = maxBytePerOutput;
        this.out = outputStreamSupplier.get();
    }

    @Override
    public synchronized void write(byte[] bytes) throws IOException {
        final int remainingBytesInVol = (int) (maxBytePerVolume - bytesInCurrentVolume);
        if (remainingBytesInVol >= bytes.length) {
            out.write(bytes);
            bytesInCurrentVolume += bytes.length;
            return;
        }

        out.write(bytes, 0, remainingBytesInVol);
        switchOutput();

        this.write(bytes, remainingBytesInVol, bytes.length - remainingBytesInVol);
    }

    @Override
    public synchronized void write(int b) throws IOException {
        if (bytesInCurrentVolume + 1 <= maxBytePerVolume) {
            out.write(b);
            bytesInCurrentVolume += 1;
            return;
        }

        switchOutput();
        out.write(b);
        bytesInCurrentVolume += 1;
    }

    @Override
    public synchronized void write(byte[] b, int off, int len) throws IOException {
        final int remainingBytesInVol = (int) (maxBytePerVolume - bytesInCurrentVolume);
        if (remainingBytesInVol >= len) {
            out.write(b, off, len);
            bytesInCurrentVolume += len;
            return;
        }

        out.write(b, off, remainingBytesInVol);
        switchOutput();
        this.write(b, off + remainingBytesInVol, len - remainingBytesInVol);
        bytesInCurrentVolume += len - remainingBytesInVol;
    }

    private void switchOutput() throws IOException {
        out.flush();
        out.close();

        out = outputStreamSupplier.get();
        bytesInCurrentVolume = 0;
    }

    @Override
    public synchronized void close() throws IOException {
        out.close();
    }

    @Override
    public synchronized void flush() throws IOException {
        out.flush();
    }
}

这篇关于写入具有容量限制的OutputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆