How to reuse inputStream?

Quote:

    Do the project when it came before a question is read from the network to upload pictures to oss, but also to cut and compress images, which have to use to upload and crop images to inputStream, but also because they can not duplicate read inputstream , leading to crop a success, and upload failed. today we offer two ways to solve, inputStream problem can not be repeated reading.

problem analysis:

The interior has a pos inputStream pointer, when read pointer will continue to move, when to move to the end of time, we will not be able to read the writing again look at a simple example:

    String text = "测试inputStream内容";
    InputStream inputStream = new ByteArrayInputStream(text.getBytes());
    byte[] readArray = new byte[inputStream.available()];
    int readCount1 = inputStream.read(readArray);
    System.out.println("读取了" + readCount1 + "个字节");

    byte[] readArray2 = new byte[inputStream.available()];
    int readCount2 = inputStream.read(readArray2);
    System.out.println("读取了" + readCount2 + "个字节");
    /**
    *  执行结果是
    *  读取了23个字节
    *  读取了-1个字节
    */

复制代码

As can be seen from the results of the design is really inputstream can only be read once. Note: just mention here inputStream.available () This method, local files can be directly know the size of the file, but if the data network, this the method is best not to use, because when the transmission is not continuous, the size of the data allowed to be read

problem solved:

? So how should we actually project can not solve it really only use it once inputSteam we look Solution:
Method One :
Use ByteArrayOutputStream to cache bytes, then pick up each read from the cache of the ByteArrayOutputStream. it is natural to think of the inputStream cached (of course not necessarily be said to be placed ByteArrayOutputStream, other ways may be, are cached ideas, there are many ways to achieve this more convenient)

       String text = "测试inputStream内容";
       InputStream rawInputStream = new ByteArrayInputStream(text.getBytes());
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
       byte[] buffer = new byte[1024];
       int len;
       while ((len = rawInputStream.read(buffer)) > -1) {
           outputStream.write(buffer, 0, len);
       }
       outputStream.flush();
       InputStream in1 = new ByteArrayInputStream(outputStream.toByteArray());
       InputStream in2 = new ByteArrayInputStream(outputStream.toByteArray());
       int readCount1 = in1.read(buffer);
       int readCount2 = in2.read(buffer);
       System.out.println("读取了" + readCount1 + "个字节");
       System.out.println("读取了" + readCount2 + "个字节");
       /**
       *  执行结果是
       *  读取了23个字节
       *  读取了23个字节
       *
复制代码

Here is the first inputStream read data to output, and then to re-use content inputStream in time, we will remove the data output in the (very magical setting, output can repeatedly take, input can only be read once)

Method Two :
In fact, there inputStream operation pointer method, mark and reset, listen to know the name and mark is reset before using inputSteam we mark the next location inputStream pointer, after reading finished, reset, and then it can be repeated. using our look at the code:

      String text = "测试inputStream内容";
      InputStream rawInputStream = new ByteArrayInputStream(text.getBytes());
      byte[] readArray = new byte[1024];
      rawInputStream.mark(0);
      int readCount1 = rawInputStream.read(readArray);
      rawInputStream.reset();
      int readCount2 = rawInputStream.read(readArray);
      System.out.println("读取了" + readCount1 + "个字节");
      System.out.println("读取了" + readCount2 + "个字节");
复制代码

to sum up:

1.inputStream can only be read once, that can only be called read () or read other arguments () method once, read out at the next call is -1, doing the project do not forget this, and which could lead to pit appearance;
2. You can use the cache or mark / reset method to reuse inputStream, to note here is that if inputStream a lot of memory if a lot of content, the cache is not a good idea, because before you are finished will occupy ( I encountered this, and then there are lots of pictures uploaded cache, resulting in insufficient memory has been fullGC, then cpu first burst);
3. there is also a small point is finished do not forget to turn off the use of inputStream / outputSteam.

Guess you like

Origin juejin.im/post/5d18c144518825559f46eeb3