如何克隆输入流?

发布于 2024-11-06 04:42:03 字数 926 浏览 3 评论 0 原文

我有一个输入流,我将其传递给一个方法来进行一些处理。我将在其他方法中使用相同的InputStream,但是在第一次处理之后,InputStream在方法内部出现关闭。

我如何克隆InputStream以发送到关闭他的方法?还有其他解决方案吗?

编辑:关闭输入流的方法是来自库的外部方法。我无法控制是否关闭。

private String getContent(HttpURLConnection con) {
    InputStream content = null;
    String charset = "";
    try {
        content = con.getInputStream();
        CloseShieldInputStream csContent = new CloseShieldInputStream(content);
        charset = getCharset(csContent);            
        return  IOUtils.toString(content,charset);
    } catch (Exception e) {
        System.out.println("Error downloading page: " + e);
        return null;
    }
}

private String getCharset(InputStream content) {
    try {
        Source parser = new Source(content);
        return parser.getEncoding();
    } catch (Exception e) {
        System.out.println("Error determining charset: " + e);
        return "UTF-8";
    }
}

I have a InputStream that I pass to a method to do some processing. I will use the same InputStream in other method, but after the first processing, the InputStream appears be closed inside the method.

How I can clone the InputStream to send to the method that closes him? There is another solution?

EDIT: the methods that closes the InputStream is an external method from a lib. I dont have control about closing or not.

private String getContent(HttpURLConnection con) {
    InputStream content = null;
    String charset = "";
    try {
        content = con.getInputStream();
        CloseShieldInputStream csContent = new CloseShieldInputStream(content);
        charset = getCharset(csContent);            
        return  IOUtils.toString(content,charset);
    } catch (Exception e) {
        System.out.println("Error downloading page: " + e);
        return null;
    }
}

private String getCharset(InputStream content) {
    try {
        Source parser = new Source(content);
        return parser.getEncoding();
    } catch (Exception e) {
        System.out.println("Error determining charset: " + e);
        return "UTF-8";
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

故事和酒 2024-11-13 04:42:03

如果您只想多次读取相同的信息,并且输入数据足够小以适合内存,则可以将数据从 InputStream 复制到 ByteArrayOutputStream

然后,您可以获得关联的字节数组并打开尽可能多的“克隆” ByteArrayInputStream,如您所愿。

ByteArrayOutputStream baos = new ByteArrayOutputStream();

// Code simulating the copy
// You could alternatively use NIO
// And please, unlike me, do something about the Exceptions :D
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1 ) {
    baos.write(buffer, 0, len);
}
baos.flush();
    
// Open new InputStreams using recorded bytes
// Can be repeated as many times as you wish
InputStream is1 = new ByteArrayInputStream(baos.toByteArray()); 
InputStream is2 = new ByteArrayInputStream(baos.toByteArray()); 

但如果您确实需要保持原始流打开以接收新数据,那么您将需要跟踪对 close() 的外部调用。您需要以某种方式防止 close() 被调用。

更新(2019):

从 Java 9 开始,中间位可以替换为 InputStream.transferTo

ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
InputStream firstClone = new ByteArrayInputStream(baos.toByteArray()); 
InputStream secondClone = new ByteArrayInputStream(baos.toByteArray()); 

If all you want to do is read the same information more than once, and the input data is small enough to fit into memory, you can copy the data from your InputStream to a ByteArrayOutputStream.

Then you can obtain the associated array of bytes and open as many "cloned" ByteArrayInputStreams as you like.

ByteArrayOutputStream baos = new ByteArrayOutputStream();

// Code simulating the copy
// You could alternatively use NIO
// And please, unlike me, do something about the Exceptions :D
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1 ) {
    baos.write(buffer, 0, len);
}
baos.flush();
    
// Open new InputStreams using recorded bytes
// Can be repeated as many times as you wish
InputStream is1 = new ByteArrayInputStream(baos.toByteArray()); 
InputStream is2 = new ByteArrayInputStream(baos.toByteArray()); 

But if you really need to keep the original stream open to receive new data, then you will need to track the external call to close(). You will need to prevent close() from being called somehow.

UPDATE (2019):

Since Java 9 the the middle bits can be replaced with InputStream.transferTo:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
InputStream firstClone = new ByteArrayInputStream(baos.toByteArray()); 
InputStream secondClone = new ByteArrayInputStream(baos.toByteArray()); 
无声无音无过去 2024-11-13 04:42:03

您想使用 Apache 的 CloseShieldInputStream

这是一个包装器,可防止流被关闭。你会做这样的事情。

InputStream is = null;

is = getStream(); //obtain the stream 
CloseShieldInputStream csis = new CloseShieldInputStream(is);

// call the bad function that does things it shouldn't
badFunction(csis);

// happiness follows: do something with the original input stream
is.read();

You want to use Apache's CloseShieldInputStream:

This is a wrapper that will prevent the stream from being closed. You'd do something like this.

InputStream is = null;

is = getStream(); //obtain the stream 
CloseShieldInputStream csis = new CloseShieldInputStream(is);

// call the bad function that does things it shouldn't
badFunction(csis);

// happiness follows: do something with the original input stream
is.read();
高冷爸爸 2024-11-13 04:42:03

您无法克隆它,并且如何解决问题取决于数据的来源。

一种解决方案是将所有数据从 InputStream 读取到字节数组中,然后围绕该字节数组创建一个 ByteArrayInputStream,并将该输入流传递到您的方法中。

编辑1:
也就是说,如果其他方法也需要读取相同的数据。即您想要“重置”流。

You can't clone it, and how you are going to solve your problem depends on what the source of the data is.

One solution is to read all data from the InputStream into a byte array, and then create a ByteArrayInputStream around that byte array, and pass that input stream into your method.

Edit 1:
That is, if the other method also needs to read the same data. I.e you want to "reset" the stream.

淡淡離愁欲言轉身 2024-11-13 04:42:03

如果从流中读取的数据很大,我建议使用 Apache Commons IO 中的 TeeInputStream。这样,您基本上可以复制输入并传递 td 管道作为您的克隆。

If the data read from the stream is large, I would recommend using a TeeInputStream from Apache Commons IO. That way you can essentially replicate the input and pass a t'd pipe as your clone.

第几種人 2024-11-13 04:42:03

这可能不适用于所有情况,但这就是我所做的:我扩展了 FilterInputStream 类并在外部库读取数据时对字节进行所需的处理。

public class StreamBytesWithExtraProcessingInputStream extends FilterInputStream {

    protected StreamBytesWithExtraProcessingInputStream(InputStream in) {
        super(in);
    }

    @Override
    public int read() throws IOException {
        int readByte = super.read();
        processByte(readByte);
        return readByte;
    }

    @Override
    public int read(byte[] buffer, int offset, int count) throws IOException {
        int readBytes = super.read(buffer, offset, count);
        processBytes(buffer, offset, readBytes);
        return readBytes;
    }

    private void processBytes(byte[] buffer, int offset, int readBytes) {
       for (int i = 0; i < readBytes; i++) {
           processByte(buffer[i + offset]);
       }
    }

    private void processByte(int readByte) {
       // TODO do processing here
    }

}

然后,您只需传递一个 StreamBytesWithExtraProcessingInputStream 实例,您将在其中传递输入流。使用原始输入流作为构造函数参数。

应该注意的是,这是逐字节工作的,因此如果需要高性能,请不要使用它。

This might not work in all situations, but here is what I did: I extended the FilterInputStream class and do the required processing of the bytes as the external lib reads the data.

public class StreamBytesWithExtraProcessingInputStream extends FilterInputStream {

    protected StreamBytesWithExtraProcessingInputStream(InputStream in) {
        super(in);
    }

    @Override
    public int read() throws IOException {
        int readByte = super.read();
        processByte(readByte);
        return readByte;
    }

    @Override
    public int read(byte[] buffer, int offset, int count) throws IOException {
        int readBytes = super.read(buffer, offset, count);
        processBytes(buffer, offset, readBytes);
        return readBytes;
    }

    private void processBytes(byte[] buffer, int offset, int readBytes) {
       for (int i = 0; i < readBytes; i++) {
           processByte(buffer[i + offset]);
       }
    }

    private void processByte(int readByte) {
       // TODO do processing here
    }

}

Then you simply pass an instance of StreamBytesWithExtraProcessingInputStream where you would have passed in the input stream. With the original input stream as constructor parameter.

It should be noted that this works byte for byte, so don't use this if high performance is a requirement.

时光瘦了 2024-11-13 04:42:03

UPD。
之前看了一下评论。这不完全是所问的内容。

如果您使用的是 apache.commons ,您可以使用 IOUtils 复制流。

您可以使用以下代码:

InputStream = IOUtils.toBufferedInputStream(toCopy);

这是适合您情况的完整示例:

public void cloneStream() throws IOException{
    InputStream toCopy=IOUtils.toInputStream("aaa");
    InputStream dest= null;
    dest=IOUtils.toBufferedInputStream(toCopy);
    toCopy.close();
    String result = new String(IOUtils.toByteArray(dest));
    System.out.println(result);
}

此代码需要一些依赖项:

MAVEN

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

GRADLE

'commons-io:commons-io:2.4'

以下是此方法的 DOC 参考:

获取输入流的全部内容并表示相同的数据
结果输入流。此方法在以下情况很有用:

源输入流速度很慢。它具有关联的网络资源,因此我们
不能长时间保持打开状态。它与网络超时相关。

您可以在此处找到有关 IOUtils 的更多信息:
http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#toBufferedInputStream(java.io.InputStream)

UPD.
Check the comment before. It isn't exactly what was asked.

If you are using apache.commons you may copy streams using IOUtils .

You can use following code:

InputStream = IOUtils.toBufferedInputStream(toCopy);

Here is the full example suitable for your situation:

public void cloneStream() throws IOException{
    InputStream toCopy=IOUtils.toInputStream("aaa");
    InputStream dest= null;
    dest=IOUtils.toBufferedInputStream(toCopy);
    toCopy.close();
    String result = new String(IOUtils.toByteArray(dest));
    System.out.println(result);
}

This code requires some dependencies:

MAVEN

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

GRADLE

'commons-io:commons-io:2.4'

Here is the DOC reference for this method:

Fetches entire contents of an InputStream and represent same data as
result InputStream. This method is useful where,

Source InputStream is slow. It has network resources associated, so we
cannot keep it open for long time. It has network timeout associated.

You can find more about IOUtils here:
http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#toBufferedInputStream(java.io.InputStream)

·深蓝 2024-11-13 04:42:03

下面是 Kotlin 的解决方案。

您可以将InputStream复制到ByteArray中。

val inputStream = ...

val byteOutputStream = ByteArrayOutputStream()
inputStream.use { input ->
    byteOutputStream.use { output ->
        input.copyTo(output)
    }
}

val byteInputStream = ByteArrayInputStream(byteOutputStream.toByteArray())

如果您需要多次读取byteInputStream,请在再次读取之前调用byteInputStream.reset()

https://code.luasoftware.com/tutorials/kotlin/how - 克隆输入流/

Below is the solution with Kotlin.

You can copy your InputStream into ByteArray

val inputStream = ...

val byteOutputStream = ByteArrayOutputStream()
inputStream.use { input ->
    byteOutputStream.use { output ->
        input.copyTo(output)
    }
}

val byteInputStream = ByteArrayInputStream(byteOutputStream.toByteArray())

If you need to read the byteInputStream multiple times, call byteInputStream.reset() before reading again.

https://code.luasoftware.com/tutorials/kotlin/how-to-clone-inputstream/

梦里人 2024-11-13 04:42:03

克隆输入流可能不是一个好主意,因为这需要深入了解所克隆的输入流的详细信息。解决此问题的方法是创建一个新的输入流,再次从同一源读取。

因此,使用某些 Java 8 功能,情况将如下所示:

public class Foo {

    private Supplier<InputStream> inputStreamSupplier;

    public void bar() {
        procesDataThisWay(inputStreamSupplier.get());
        procesDataTheOtherWay(inputStreamSupplier.get());
    }

    private void procesDataThisWay(InputStream) {
        // ...
    }

    private void procesDataTheOtherWay(InputStream) {
        // ...
    }
}

此方法具有积极的效果,它将重用已存在的代码 - 创建封装在 inputStreamSupplier 中的输入流。并且不需要为流的克隆维护第二个代码路径。

另一方面,如果从流中读取数据的成本很高(因为它是通过低带宽连接完成的),那么此方法将使成本加倍。这可以通过使用特定的供应商来规避,该供应商将首先在本地存储流内容并为现在的本地资源提供一个InputStream

Cloning an input stream might not be a good idea, because this requires deep knowledge about the details of the input stream being cloned. A workaround for this is to create a new input stream that reads from the same source again.

So using some Java 8 features this would look like this:

public class Foo {

    private Supplier<InputStream> inputStreamSupplier;

    public void bar() {
        procesDataThisWay(inputStreamSupplier.get());
        procesDataTheOtherWay(inputStreamSupplier.get());
    }

    private void procesDataThisWay(InputStream) {
        // ...
    }

    private void procesDataTheOtherWay(InputStream) {
        // ...
    }
}

This method has the positive effect that it will reuse code that is already in place - the creation of the input stream encapsulated in inputStreamSupplier. And there is no need to maintain a second code path for the cloning of the stream.

On the other hand, if reading from the stream is expensive (because a it's done over a low bandwith connection), then this method will double the costs. This could be circumvented by using a specific supplier that will store the stream content locally first and provide an InputStream for that now local resource.

静若繁花 2024-11-13 04:42:03

下面的课程应该可以解决这个问题。只需创建一个实例,调用“乘法”方法,并提供源输入流和所需的重复项数量。

重要提示:您必须在单独的线程中同时使用所有克隆流。

package foo.bar;

import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class InputStreamMultiplier {
    protected static final int BUFFER_SIZE = 1024;
    private ExecutorService executorService = Executors.newCachedThreadPool();

    public InputStream[] multiply(final InputStream source, int count) throws IOException {
        PipedInputStream[] ins = new PipedInputStream[count];
        final PipedOutputStream[] outs = new PipedOutputStream[count];

        for (int i = 0; i < count; i++)
        {
            ins[i] = new PipedInputStream();
            outs[i] = new PipedOutputStream(ins[i]);
        }

        executorService.execute(new Runnable() {
            public void run() {
                try {
                    copy(source, outs);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        return ins;
    }

    protected void copy(final InputStream source, final PipedOutputStream[] outs) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        int n = 0;
        try {
            while (-1 != (n = source.read(buffer))) {
                //write each chunk to all output streams
                for (PipedOutputStream out : outs) {
                    out.write(buffer, 0, n);
                }
            }
        } finally {
            //close all output streams
            for (PipedOutputStream out : outs) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

The class below should do the trick. Just create an instance, call the "multiply" method, and provide the source input stream and the amount of duplicates you need.

Important: you must consume all cloned streams simultaneously in separate threads.

package foo.bar;

import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class InputStreamMultiplier {
    protected static final int BUFFER_SIZE = 1024;
    private ExecutorService executorService = Executors.newCachedThreadPool();

    public InputStream[] multiply(final InputStream source, int count) throws IOException {
        PipedInputStream[] ins = new PipedInputStream[count];
        final PipedOutputStream[] outs = new PipedOutputStream[count];

        for (int i = 0; i < count; i++)
        {
            ins[i] = new PipedInputStream();
            outs[i] = new PipedOutputStream(ins[i]);
        }

        executorService.execute(new Runnable() {
            public void run() {
                try {
                    copy(source, outs);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        return ins;
    }

    protected void copy(final InputStream source, final PipedOutputStream[] outs) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        int n = 0;
        try {
            while (-1 != (n = source.read(buffer))) {
                //write each chunk to all output streams
                for (PipedOutputStream out : outs) {
                    out.write(buffer, 0, n);
                }
            }
        } finally {
            //close all output streams
            for (PipedOutputStream out : outs) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
独木成林 2024-11-13 04:42:03

通过示例增强 @Anthony Accioly

InputStream:克隆 < code>bytes-Stream 并以列表集合的形式提供副本数量。

public static List<InputStream> multiplyBytes(InputStream input, int cloneCount) throws IOException {
    List<InputStream> copies = new ArrayList<InputStream>();
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    copy(input, baos);
    
    for (int i = 0; i < cloneCount; i++) {
        copies.add(new ByteArrayInputStream(baos.toByteArray()));
    }
    return copies;
}
// IOException - If reading the Reader or Writing into the Writer goes wrong.
public static void copy(Reader in, Writer out) throws IOException {
    try {
        char[] buffer = new char[1024];
        int nrOfBytes = -1;
        while ((nrOfBytes = in.read(buffer)) != -1) {
            out.write(buffer, 0, nrOfBytes);
        }
        out.flush();
    } finally {
        close(in);
        close(out);
    }
}

Reader:克隆 < code>chars-Stream 并以列表集合的形式提供副本数量。

public static List<Reader> multiplyChars(Reader reader, int cloneCOunt) throws IOException {
    List<Reader> copies = new ArrayList<Reader>();
    BufferedReader bufferedInput = new BufferedReader(reader);
    StringBuffer buffer = new StringBuffer();
    String delimiter = System.getProperty("line.separator");
    String line;
    while ((line = bufferedInput.readLine()) != null) {
        if (!buffer.toString().equals(""))
            buffer.append(delimiter);
        buffer.append(line);
    }
    close(bufferedInput);
    for (int i = 0; i < cloneCOunt; i++) {
        copies.add(new StringReader(buffer.toString()));
    }
    return copies;
}
public static void copy(InputStream in, OutputStream out) throws IOException {
    try {
        byte[] buffer = new byte[1024];
        int nrOfBytes = -1;
        while ((nrOfBytes = in.read(buffer)) != -1) {
            out.write(buffer, 0, nrOfBytes);
        }
        out.flush();
    } finally {
        close(in);
        close(out);
    }
}

完整示例:

public class SampleTest {

    public static void main(String[] args) throws IOException {
        String filePath = "C:/Yash/StackoverflowSSL.cer";
        InputStream fileStream = new FileInputStream(new File(filePath) );
        
        List<InputStream> bytesCopy = multiplyBytes(fileStream, 3);
        for (Iterator<InputStream> iterator = bytesCopy.iterator(); iterator.hasNext();) {
            InputStream inputStream = (InputStream) iterator.next();
            System.out.println("Byte Stream:"+ inputStream.available()); // Byte Stream:1784
        }
        printInputStream(bytesCopy.get(0));
        
        //java.sql.Clob clob = ((Clob) getValue(sql)); - clob.getCharacterStream();
        Reader stringReader = new StringReader("StringReader that reads Characters from the specified string.");
        List<Reader> charsCopy = multiplyChars(stringReader, 3);
        for (Iterator<Reader> iterator = charsCopy.iterator(); iterator.hasNext();) {
            Reader reader = (Reader) iterator.next();
            System.out.println("Chars Stream:"+reader.read()); // Chars Stream:83
        }
        printReader(charsCopy.get(0));
    }
    
    // Reader, InputStream - Prints the contents of the reader to System.out.
    public static void printReader(Reader reader) throws IOException {
        BufferedReader br = new BufferedReader(reader);
        String s;
        while ((s = br.readLine()) != null) {
            System.out.println(s);
        }
    }
    public static void printInputStream(InputStream inputStream) throws IOException {
        printReader(new InputStreamReader(inputStream));
    }

    // Closes an opened resource, catching any exceptions.
    public static void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (IOException e) {
                System.err.println(e);
            }
        }
    }
}

Enhancing the @Anthony Accioly with the example.

InputStream: Clones the bytes-Stream and provides number of copies as a List Collection.

public static List<InputStream> multiplyBytes(InputStream input, int cloneCount) throws IOException {
    List<InputStream> copies = new ArrayList<InputStream>();
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    copy(input, baos);
    
    for (int i = 0; i < cloneCount; i++) {
        copies.add(new ByteArrayInputStream(baos.toByteArray()));
    }
    return copies;
}
// IOException - If reading the Reader or Writing into the Writer goes wrong.
public static void copy(Reader in, Writer out) throws IOException {
    try {
        char[] buffer = new char[1024];
        int nrOfBytes = -1;
        while ((nrOfBytes = in.read(buffer)) != -1) {
            out.write(buffer, 0, nrOfBytes);
        }
        out.flush();
    } finally {
        close(in);
        close(out);
    }
}

Reader: Clones the chars-Stream and provides number of copies as a List Collection.

public static List<Reader> multiplyChars(Reader reader, int cloneCOunt) throws IOException {
    List<Reader> copies = new ArrayList<Reader>();
    BufferedReader bufferedInput = new BufferedReader(reader);
    StringBuffer buffer = new StringBuffer();
    String delimiter = System.getProperty("line.separator");
    String line;
    while ((line = bufferedInput.readLine()) != null) {
        if (!buffer.toString().equals(""))
            buffer.append(delimiter);
        buffer.append(line);
    }
    close(bufferedInput);
    for (int i = 0; i < cloneCOunt; i++) {
        copies.add(new StringReader(buffer.toString()));
    }
    return copies;
}
public static void copy(InputStream in, OutputStream out) throws IOException {
    try {
        byte[] buffer = new byte[1024];
        int nrOfBytes = -1;
        while ((nrOfBytes = in.read(buffer)) != -1) {
            out.write(buffer, 0, nrOfBytes);
        }
        out.flush();
    } finally {
        close(in);
        close(out);
    }
}

Full Example:

public class SampleTest {

    public static void main(String[] args) throws IOException {
        String filePath = "C:/Yash/StackoverflowSSL.cer";
        InputStream fileStream = new FileInputStream(new File(filePath) );
        
        List<InputStream> bytesCopy = multiplyBytes(fileStream, 3);
        for (Iterator<InputStream> iterator = bytesCopy.iterator(); iterator.hasNext();) {
            InputStream inputStream = (InputStream) iterator.next();
            System.out.println("Byte Stream:"+ inputStream.available()); // Byte Stream:1784
        }
        printInputStream(bytesCopy.get(0));
        
        //java.sql.Clob clob = ((Clob) getValue(sql)); - clob.getCharacterStream();
        Reader stringReader = new StringReader("StringReader that reads Characters from the specified string.");
        List<Reader> charsCopy = multiplyChars(stringReader, 3);
        for (Iterator<Reader> iterator = charsCopy.iterator(); iterator.hasNext();) {
            Reader reader = (Reader) iterator.next();
            System.out.println("Chars Stream:"+reader.read()); // Chars Stream:83
        }
        printReader(charsCopy.get(0));
    }
    
    // Reader, InputStream - Prints the contents of the reader to System.out.
    public static void printReader(Reader reader) throws IOException {
        BufferedReader br = new BufferedReader(reader);
        String s;
        while ((s = br.readLine()) != null) {
            System.out.println(s);
        }
    }
    public static void printInputStream(InputStream inputStream) throws IOException {
        printReader(new InputStreamReader(inputStream));
    }

    // Closes an opened resource, catching any exceptions.
    public static void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (IOException e) {
                System.err.println(e);
            }
        }
    }
}

爱你不解释 2024-11-13 04:42:03

如果InputStream不太大,可以使用org.apache.commons.io.IOUtils轻松读取字节并保存在内存中,以供以后多次使用:

@Test
@SneakyThrows
public void cloneInputStream() {
    InputStream originIS = IOUtils.toInputStream("abcdefghijklmnopqrstuvwxyz", UTF_8);
    byte[] bytes = IOUtils.toByteArray(originIS);
    InputStream clonedIS1 = new ByteArrayInputStream(bytes);
    InputStream clonedIS2 = new ByteArrayInputStream(bytes);
    System.out.println(IOUtils.toString(originIS, UTF_8)); // null, inputstream is empty
    System.out.println(IOUtils.toString(clonedIS1, UTF_8)); // ok
    System.out.println(IOUtils.toString(clonedIS2, UTF_8)); // ok
}

if InputStream is not too big, use org.apache.commons.io.IOUtils to easily read bytes and save in memory, for use later many times:

@Test
@SneakyThrows
public void cloneInputStream() {
    InputStream originIS = IOUtils.toInputStream("abcdefghijklmnopqrstuvwxyz", UTF_8);
    byte[] bytes = IOUtils.toByteArray(originIS);
    InputStream clonedIS1 = new ByteArrayInputStream(bytes);
    InputStream clonedIS2 = new ByteArrayInputStream(bytes);
    System.out.println(IOUtils.toString(originIS, UTF_8)); // null, inputstream is empty
    System.out.println(IOUtils.toString(clonedIS1, UTF_8)); // ok
    System.out.println(IOUtils.toString(clonedIS2, UTF_8)); // ok
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文