7

I used this question

How do I convert an InputStream to a String in Java?

to convert an InputStream to a String with this code:

public static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
} 

My inputstream comes from an HttpURLConnection InputStream, and when I do my conversion to String, the inputstream changes and I cannot longer use it. This is the error that I get:

Premature end of file.' SOAP

What can I do to keep my inputstream, when I convert it to string with the proper information?.

Speciffically this is the information that changes:

inCache = true (before false)
keepAliveConnections = 4 (before 5)
keepingAlive = false (before true)
poster = null (before it was PosterOutputStream object with values)

Thank you.

Community
  • 1
  • 1
Eduardo
  • 19,928
  • 23
  • 65
  • 73
  • Eduardo: is it possible for you to create another InputStream and use it for the second client? After reading data in this method (convertStreamToString) you can put this data back into another stream (e.g: ByteArrayInputStream) and then send it to your second client that needs to read the same data from input stream. – mhshams Nov 21 '12 at 04:38
  • Hi Mohammad, I think I don't fully get what you mean. Can you please reply to the question giving more details?. I iwll be more than happy to give you my bounty if it works fine. Yes you are right in your comment for the other question, I need to keep my InputStream intact to convert it then properly into a SOAP message. Thank you!. – Eduardo Nov 21 '12 at 08:48

3 Answers3

10

If you pass your input stream into scanner or read its data in any other way. you actually consuming its data and there will be no available data in that stream anymore.

you may need to create a new input stream with same data and use it instead of the original one. for example:

ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];

// inputStream is your original stream. 
for (int n; 0 < (n = inputStream.read(buf));) {
    into.write(buf, 0, n);
}
into.close();

byte[] data = into.toByteArray();

//This is your data in string format.
String stringData = new String(data, "UTF-8"); // Or whatever encoding  

//This is the new stream that you can pass it to other code and use its data.    
ByteArrayInputStream newStream = new ByteArrayInputStream(data);
mhshams
  • 16,384
  • 17
  • 55
  • 65
  • 1
    I see that you put 4096, It worked fine. However How can I get the size of the inputstream?, I don't see a getsize method?. Thank you!. – Eduardo Nov 21 '12 at 12:30
  • 2
    that number (4096) is the buffer size only. you can chose any other number that you like. you can't find the input stream size without reading it. you can use InputStream.available(), but it will return the current number of bytes that are available in the stream. in fact the stream size can change during the time that you are reading it. so the only guaranteed solution is the read data until you reach to the end of stream. – mhshams Nov 21 '12 at 12:43
2

The scanner reads till the end of the stream and closes it. So it will not be available further. Use PushbackInputStream as a wrapper to your input stream and use the unread() method.

Emil
  • 7,220
  • 17
  • 76
  • 135
Antony
  • 87
  • 3
  • Hi Antony, I believe that you are right. However how do I use the unread() method that you mention?. Thanks a lot!!!. – Eduardo Nov 20 '12 at 15:00
  • 1
    @Antony by using PushbackInputStream you CANNOT unread the data in the original InputStream. I think Eduardo needs to keep original InputStream (the one from URL connection) intact. – mhshams Nov 21 '12 at 04:33
0

Try to Use Apache Utilities. In my preset project, I have done the same thing

InputStream xml = connection.getInputStream();

String responseData = IOUtils.toString(xml);

You can get IOUtils from Apache [import org.apache.commons.io.IOUtils]

RaceBase
  • 18,428
  • 47
  • 141
  • 202
  • Hi, actually this is commented in the question I posted and I tried it. However I was as well consuming my inputstream and at the end it was unsuable. Thank you!. – Eduardo Nov 21 '12 at 10:25
  • You can use the string data as many times as you want. Since stream can't be read backwards and you will face lot of issues down the line for such support – RaceBase Nov 21 '12 at 10:28
  • Yes I can use the string as many times as I want, but however I needed the inputstream twice, once to be converted to String(to know the right SOAP version that I should use), and the second time to convert the inputstream to a SOAP message. – Eduardo Nov 21 '12 at 10:39
  • Still I couldn't get what's an issue using String rather than Stream for SOAP message. – RaceBase Nov 21 '12 at 11:05
  • It's not possible to convert the String to a SOAP message, only the inputstream. – Eduardo Nov 21 '12 at 12:26