Java 写入具有容量限制的OutputStream

Java 写入具有容量限制的OutputStream,java,outputstream,capacity,Java,Outputstream,Capacity,遵循我之前提出的问题:我正在实现一个具有容量限制的ByteArrayOutputStream。我的主要限制是可用内存量。所以有这样的流os: 当我向输出流写入超过1MB的数据时,我需要“停止”。 我不希望抛出异常,而是编写os 输出流到指定的其他输出流参数。 输出流输出; 操作系统写入(输出); 在那之后,从一开始就继续写os 为了防止出现第1条所述的情况,我更喜欢排水os, 尽可能频繁地。我的意思是将数据从它复制到chuncks中的out 512KB 可行吗?如果是,有什么建议吗?或者可能

遵循我之前提出的问题:我正在实现一个具有容量限制的
ByteArrayOutputStream
。我的主要限制是可用内存量。所以有这样的流
os

  • 当我向输出流写入超过1MB的数据时,我需要“停止”。 我不希望抛出异常,而是编写
    os
    输出流到指定的其他输出流参数。
    
    输出流输出;
    操作系统写入(输出);
    
    在那之后,从一开始就继续写
    os

  • 为了防止出现第1条所述的情况,我更喜欢排水
    os
    , 尽可能频繁地。我的意思是将数据从它复制到chuncks中的
    out
    512KB 可行吗?如果是,有什么建议吗?或者可能有一个内置的类来满足我的要求

  • 编辑:写入
    out
    的字节数也受到限制。我最多可以在那里写1GB。如果我有更多,我需要创建其他输出流,以便从
    os
    中排出。
    写入操作系统的过程。可能是这样。500兆写在那里-我立即把它转出。几秒钟后,700MB被写入到那里-我只需要将500MB的内存消耗到
    out
    ,将200MB的内存消耗到其他outputstream(
    out2
    ),在这种情况下,我需要创建一个BufferedOutputStream,您可以这样构造:

    new BufferedOutputStream(out, 512000)
    
    第一个参数是您拥有的另一个outputstream,第二个参数是BufferedOutputStream内部缓冲区的大小

    编辑:

    好的,一开始我并不完全理解你的需要。您确实需要扩展OutputStream来实现这一点。下面是一个示例代码:

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

        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");
        }
    
    OutputStreamMultiVolume的第一个构造函数参数是卷的最大大小。如果达到此大小,我们将关闭当前outputStream,并调用outputStream供应商获取下一个

    这里的示例代码将字符串
    012345678901234567890123456789012345678901234567890123456789
    (5倍于0123456789)写入名为“sample.file.idx.txt”的文件中,每当我们达到超出流的最大大小时,idx都会增加(因此您将得到5个文件)

    而课堂本身:

    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多卷扩展OutputStream{
    专用最终长maxBytePerVolume;
    私用长字节数InCurrentVolume=0;
    私有输出流输出;
    私人OutputStreamSupplier OutputStreamSupplier;
    静态接口输出流供应商{
    OutputStream get()抛出IOException;
    }
    公共OutputStreamMultiVolume(长maxBytePerOutput、OutputStreamSupplier OutputStreamSupplier)引发IOException{
    this.outputStreamSupplier=outputStreamSupplier;
    this.maxBytePerVolume=maxBytePerOutput;
    this.out=outputStreamSupplier.get();
    }
    @凌驾
    公共同步的无效写入(字节[]字节)引发IOException{
    最终整数剩余BytesInvol=(整数)(maxBytePerVolume-bytesInCurrentVolume);
    if(remainingBytesInVol>=字节.length){
    out.write(字节);
    ByteSirrentVolume+=字节数。长度;
    返回;
    }
    out.write(字节,0,剩余字节数invol);
    开关输出();
    this.write(bytes,remainingBytesInVol,bytes.length-remainingBytesInVol);
    }
    @凌驾
    公共同步的无效写入(int b)引发IOException{
    if(字节数,单位体积+1=len){
    注销(b,注销,len);
    ByteSirrentVolume+=len;
    返回;
    }
    注销(b、注销、剩余发票);
    开关输出();
    本.冲销(b,off+remainingBytesInVol,len-remainingBytesInVol);
    BytesIncirentVolume+=len-剩余BytesInvol;
    }
    私有void switchOutput()引发IOException{
    out.flush();
    out.close();
    out=outputStreamSupplier.get();
    ByteSirrentVolume=0;
    }
    @凌驾
    public synchronized void close()引发IOException{
    out.close();
    }
    @凌驾
    public synchronized void flush()引发IOException{
    out.flush();
    }
    }
    
    您描述的是一个BufferedOutputStream,您可以这样构造:

    new BufferedOutputStream(out, 512000)
    
    第一个参数是您拥有的另一个outputstream,第二个参数是BufferedOutputStream内部缓冲区的大小

    编辑:

    好的,一开始我并不完全理解你的需要。您确实需要扩展OutputStream来实现这一点。下面是一个示例代码:

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

        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");
        }
    
    OutputStreamMultiVolume的第一个构造函数参数是卷的最大大小。如果达到此大小,我们将关闭当前outputStream,并调用outputStream供应商获取下一个

    这里的示例代码将字符串
    012345678901234567890123456789012345678901234567890123456789
    (5倍于0123456789)写入名为“sample.file.idx.txt”的文件中,每当我们达到超出流的最大大小时,idx都会增加(因此您将得到5个文件)

    而课堂本身:

    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多卷扩展OutputStream{
    专用最终长maxBytePerVolume;
    私用长字节数InCurrentVolume=0;
    私有输出流输出;
    私人OutputStreamSupplier OutputStreamSupplier;
    静态接口输出流供应商{
    OutputStream get()抛出IOException;
    }
    公共OutputStreamMultiVolume(长maxBytePerOutput、OutputStreamSupplier OutputStreamSupplier)引发IOException{
    this.outputStreamSupplier=outputStreamSupplier;
    this.maxBytePerVolume=maxBytePerOutput;
    this.out=outputStreamSupplier.get();
    }
    @凌驾
    公共同步的无效写入(字节[]字节)引发IOException{
    最终整型剩余
    
    Timer timer=new Timer(true);
    TimerTask timerTask=new TimerTask(){
       public void run()
       {
            try
            {
                out.flush();
            }
            catch (IOException e)
            {
                ...
            }
    };
    timer.schedule(timerTask, delay, period);