phil swenson
phil swenson

Reputation: 8894

Convert Stream to String Java/Groovy

I stole this snippet off the web. But it looks to be limited to 4096 bytes and is quite ugly IMO. Anyone know of a better approach? I'm actually using Groovy btw...

String streamToString(InputStream input) {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        for (int n; (n = input.read(b)) != -1;) {
            out.append(new String(b, 0, n));
        }
        return out.toString();
    }

EDIT:

I found a better solution in Groovy:

InputStream exportTemplateStream = getClass().getClassLoader().getResourceAsStream("export.template")
assert exportTemplateStream: "[export.template stream] resource not found"
String exportTemplate = exportTemplateStream.text

Upvotes: 30

Views: 41814

Answers (8)

AechoLiu
AechoLiu

Reputation: 18398

For Groovy

filePath = ... //< a FilePath object
stream = filePath.read() //< InputStream object

// Specify the encoding, and get the String object
//content = stream.getText("UTF-16") 
content = stream.getText("UTF-8") 

The InputStream class reference

The getText() without encoding, it will use current system encoding, ex ("UTF-8").

Upvotes: 17

rfranr
rfranr

Reputation: 56

You can try something similar to this

new FileInputStream( new File("c:/tmp/file.txt") ).eachLine { println it }

Upvotes: 0

phil swenson
phil swenson

Reputation: 8894

Some good and fast answers. However I think the best one is Groovy has added a "getText" method to InputStream. So all I had to do was stream.text. And good call on the 4096 comment.

Upvotes: 59

Noah Ternullo
Noah Ternullo

Reputation: 677

For future reviewers who have similar problems, please note that both IOUtils from Apache, and Groovy's InputStream.getText() method require the stream to complete, or be closed before returning. If you are working with a persistent stream you will nead to deal with the "ugly" example that Phil originally posted, or work with non-blocking IO.

Upvotes: 1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340743

Try IOUtils from Apache Commons:

String s = IOUtils.toString(inputStream, "UTF-8");

Upvotes: 8

Anon
Anon

Reputation: 2348

That snippet has a bug: if the input uses a multi-byte character encoding, there's a good chance that a single character will span two reads (and not be convertable). And it also has the semi-bug that it relies on the platform's default encoding.

Instead, use Jakarta Commons IO. In particular, the version of IOUtils.toString() that takes an InputStream and applies an encoding to it.

Upvotes: 2

Afiefh
Afiefh

Reputation: 1067

It's reading the input in chunks of 4096 bytes(4KB), but the size of the actual string is not limited as it keeps reading more and appending it to the SringBuffer.

Upvotes: 5

jjnguy
jjnguy

Reputation: 138884

You can do it fairly easily using the Scanner class:

String streamToSring(InputStream input) {
    Scanner s = new Scanner(input);
    StringBuilder builder = new StringBuilder();
    while (s.hasNextLine()) {
        builder.append(s.nextLine() +"\n");
    }
    return builder.toString();
}

Upvotes: 4

Related Questions