本文主要是介绍Java中InputStream重复使用问题的几种解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Java中InputStream重复使用问题的几种解决方案》在Java开发中,InputStream是用于读取字节流的类,在许多场景下,我们可能需要重复读取InputStream中的数据,这篇文章主...
前言
在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("China编程第一次使用:"); readAndPrint(reusableStream1); // 使用流2 System.out.println("第二次使用:"); readAndPrint(reusableStream2); } private static byte[] readAllBytes(InputStream is) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); python 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. 使用Awww.chinasem.cnpache 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);
InputStr编程eam 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 ByteArrayInputStreamjs(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重复使用内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Java中InputStream重复使用问题的几种解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!