当前位置: 代码网 > it编程>编程语言>Java > Java中InputStream重复使用问题的几种解决方案

Java中InputStream重复使用问题的几种解决方案

2025年08月09日 Java 我要评论
前言在java中,inputstream通常设计为"一次性"使用,读取后流会到达末尾,再次读取时会返回-1或抛出异常。以下是几种实现inputstream重复使用的方法:1. 使用

前言

在java中,inputstream通常设计为"一次性"使用,读取后流会到达末尾,再次读取时会返回-1或抛出异常。以下是几种实现inputstream重复使用的方法:

1. 使用mark()和reset()方法(适用于支持标记的流)

java

import java.io.*;

public class inputstreamreuser {
    public static void main(string[] args) throws ioexception {
        string data = "hello world";
        inputstream inputstream = new bytearrayinputstream(data.getbytes());
        
        // 第一次读取前标记
        if (inputstream.marksupported()) {
            inputstream.mark(0); // 参数是readlimit,0表示不限制
        }
        
        // 第一次读取
        system.out.println("第一次读取:");
        readandprint(inputstream);
        
        // 重置流
        if (inputstream.marksupported()) {
            inputstream.reset();
        }
        
        // 第二次读取
        system.out.println("第二次读取:");
        readandprint(inputstream);
    }
    
    private static void readandprint(inputstream is) throws ioexception {
        int content;
        while ((content = is.read()) != -1) {
            system.out.print((char) content);
        }
        system.out.println();
    }
}

2. 将流内容缓存到字节数组(最可靠方法)

java

import java.io.*;

public class inputstreamcacher {
    public static void main(string[] args) throws ioexception {
        inputstream originalstream = new fileinputstream("example.txt");
        
        // 将流内容缓存到字节数组
        byte[] bytes = readallbytes(originalstream);
        originalstream.close();
        
        // 创建可重复使用的流
        inputstream reusablestream1 = new bytearrayinputstream(bytes);
        inputstream reusablestream2 = new bytearrayinputstream(bytes);
        
        // 使用流1
        system.out.println("第一次使用:");
        readandprint(reusablestream1);
        
        // 使用流2
        system.out.println("第二次使用:");
        readandprint(reusablestream2);
    }
    
    private static byte[] readallbytes(inputstream is) throws ioexception {
        bytearrayoutputstream buffer = new bytearrayoutputstream();
        byte[] data = new byte[1024];
        int nread;
        while ((nread = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nread);
        }
        return buffer.tobytearray();
    }
    
    private static void readandprint(inputstream is) throws ioexception {
        int content;
        while ((content = is.read()) != -1) {
            system.out.print((char) content);
        }
        system.out.println();
    }
}

3. 使用apache commons io的ioutils(简化代码)

java

import org.apache.commons.io.ioutils;
import java.io.*;

public class commonsioexample {
    public static void main(string[] args) throws ioexception {
        inputstream originalstream = new fileinputstream("example.txt");
        
        // 将流转换为字节数组
        byte[] bytes = ioutils.tobytearray(originalstream);
        originalstream.close();
        
        // 创建可重复使用的流
        inputstream reusablestream1 = new bytearrayinputstream(bytes);
        inputstream reusablestream2 = new bytearrayinputstream(bytes);
        
        // 使用流
        system.out.println("第一次使用: " + ioutils.tostring(reusablestream1, "utf-8"));
        system.out.println("第二次使用: " + ioutils.tostring(reusablestream2, "utf-8"));
    }
}

4. 自定义可重置的inputstream包装器

java

import java.io.*;

public class resettableinputstream extends inputstream {
    private final inputstream original;
    private inputstream current;
    private byte[] buffer;
    private boolean buffered = false;
    
    public resettableinputstream(inputstream original) {
        this.original = original;
        this.current = original;
    }
    
    @override
    public int read() throws ioexception {
        return current.read();
    }
    
    public void resetstream() throws ioexception {
        if (!buffered) {
            // 第一次重置时缓存内容
            bytearrayoutputstream baos = new bytearrayoutputstream();
            byte[] data = new byte[1024];
            int nread;
            while ((nread = original.read(data, 0, data.length)) != -1) {
                baos.write(data, 0, nread);
            }
            buffer = baos.tobytearray();
            buffered = true;
        }
        current = new bytearrayinputstream(buffer);
    }
    
    @override
    public void close() throws ioexception {
        original.close();
        if (buffered && current != null) {
            current.close();
        }
    }
}

// 使用示例
public class main {
    public static void main(string[] args) throws ioexception {
        resettableinputstream ris = new resettableinputstream(new fileinputstream("example.txt"));
        
        // 第一次读取
        system.out.println("第一次读取:");
        readandprint(ris);
        
        // 重置
        ris.resetstream();
        
        // 第二次读取
        system.out.println("第二次读取:");
        readandprint(ris);
        
        ris.close();
    }
    
    private static void readandprint(inputstream is) throws ioexception {
        int content;
        while ((content = is.read()) != -1) {
            system.out.print((char) content);
        }
        system.out.println();
    }
}

注意事项

  • 内存考虑:缓存整个流到内存中可能不适合处理非常大的文件

  • 资源释放:确保在所有使用完成后关闭流

  • 性能影响:重复读取相同的流内容会有额外的内存开销

  • 网络流:对于网络流,通常无法重置,必须先缓存内容

  • 标记支持:不是所有inputstream实现都支持mark()reset()

总结

到此这篇关于java中inputstream重复使用问题的几种解决方案的文章就介绍到这了,更多相关java中inputstream重复使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com