web-dev-qa-db-fra.com

Comment lire/convertir un InputStream en une chaîne en Java?

Si vous avez un objet Java.io.InputStream, comment devriez-vous traiter cet objet et générer une String?


Supposons que je possède une InputStream contenant des données texte et que je souhaite la convertir en String. Ainsi, je peux par exemple l'écrire dans un fichier journal.

Quel est le moyen le plus simple de convertir InputStream en String?

public String convertStreamToString(InputStream is) {
    // ???
}
3527
Johnny Maelstrom

Une bonne façon de faire est d’utiliser Apache commonsIOUtils pour copier la InputStream dans une StringWriter... quelque chose comme:

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();

ou même

// NB: does not close inputStream, you'll have to use try-with-resources for that
String theString = IOUtils.toString(inputStream, encoding); 

Sinon, vous pouvez utiliser ByteArrayOutputStream si vous ne voulez pas mélanger vos flux et écrivains.

2228
Harry Lime

Voici un moyen d'utiliser uniquement la bibliothèque Java standard (notez que le flux n'est pas fermé, votre kilométrage peut varier).

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

J'ai appris cette astuce de "Astuces stupides de scanner" article. Cela fonctionne parce que Scanner effectue une itération sur les jetons du flux. Dans ce cas, nous séparons les jetons en utilisant "début de la limite d'entrée" (\ A), ce qui nous donne un seul jeton pour tout le contenu du courant.

Remarque: si vous devez spécifier le codage du flux d'entrée, vous pouvez fournir au constructeur Scanner le deuxième argument qui indique le jeu de caractères à utiliser (par exemple, "UTF-8").

La pointe du chapeau va également à Jacob , qui m'a une fois dirigé vers ledit article.

2182
Pavel Repin

Résumez les autres réponses. J'ai trouvé 11 façons principales de le faire (voir ci-dessous). Et j'ai écrit quelques tests de performance (voir les résultats ci-dessous):

Moyens de convertir un InputStream en String:

  1. Utilisation de IOUtils.toString (Apache Utils) 

    String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    
  2. Utilisation de CharStreams (goyave) 

    String result = CharStreams.toString(new InputStreamReader(
          inputStream, Charsets.UTF_8));
    
  3. Utilisation de Scanner (JDK) 

    Scanner s = new Scanner(inputStream).useDelimiter("\\A");
    String result = s.hasNext() ? s.next() : "";
    
  4. Utilisation de Stream API (Java 8). Warning: cette solution convertit différents sauts de ligne (comme \r\n) en \n.

    String result = new BufferedReader(new InputStreamReader(inputStream))
      .lines().collect(Collectors.joining("\n"));
    
  5. Utilisation de parallel Stream API (Java 8). Warning: cette solution convertit différents sauts de ligne (comme \r\n) en \n

    String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
       .parallel().collect(Collectors.joining("\n"));
    
  6. Utilisation de InputStreamReader et StringBuilder (JDK) 

    final int bufferSize = 1024;
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    Reader in = new InputStreamReader(inputStream, "UTF-8");
    for (; ; ) {
        int rsz = in.read(buffer, 0, buffer.length);
        if (rsz < 0)
            break;
        out.append(buffer, 0, rsz);
    }
    return out.toString();
    
  7. Utilisation de StringWriter et IOUtils.copy (Apache Commons)

    StringWriter writer = new StringWriter();
    IOUtils.copy(inputStream, writer, "UTF-8");
    return writer.toString();
    
  8. Utilisation de ByteArrayOutputStream et inputStream.read (JDK) 

    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return result.toString("UTF-8");
    
  9. Utilisation de BufferedReader (JDK). Avertissement: Cette solution convertit différents sauts de ligne (tels que \n\r) en propriété système line.separator (par exemple, sous Windows, en "\ r\n").

    String newLine = System.getProperty("line.separator");
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder result = new StringBuilder();
    boolean flag = false;
    for (String line; (line = reader.readLine()) != null; ) {
        result.append(flag? newLine: "").append(line);
        flag = true;
    }
    return result.toString();
    
  10. Utilisation de BufferedInputStream et ByteArrayOutputStream (JDK) 

    BufferedInputStream bis = new BufferedInputStream(inputStream);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
        buf.write((byte) result);
        result = bis.read();
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return buf.toString("UTF-8");
    
  11. Utilisation de inputStream.read() et StringBuilder (JDK). Warning: cette solution a des problèmes avec Unicode, par exemple avec le texte russe (fonctionne correctement uniquement avec du texte non Unicode)

    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = inputStream.read()) != -1)
        sb.append((char)ch);
    reset();
    return sb.toString();
    

Attention:

  1. Les solutions 4, 5 et 9 convertissent différents sauts de ligne en un.

  2. Solution 11 ne peut pas fonctionner correctement avec le texte Unicode

Des tests de performance

Tests de performance pour les petits String (longueur = 175), url dans github (mode = Temps moyen, système = Linux, le score 1 343 est le meilleur):

              Benchmark                         Mode  Cnt   Score   Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   1,343 ± 0,028  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   6,980 ± 0,404  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   7,437 ± 0,735  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10   8,977 ± 0,328  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10  10,613 ± 0,599  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10  10,605 ± 0,527  us/op
 3. Scanner (JDK)                               avgt   10  12,083 ± 0,293  us/op
 2. CharStreams (guava)                         avgt   10  12,999 ± 0,514  us/op
 4. Stream Api (Java 8)                         avgt   10  15,811 ± 0,605  us/op
 9. BufferedReader (JDK)                        avgt   10  16,038 ± 0,711  us/op
 5. parallel Stream Api (Java 8)                avgt   10  21,544 ± 0,583  us/op

Tests de performance pour big String (length = 50100), url in github (mode = Temps moyen, système = Linux, le score 200 715 est le meilleur):

               Benchmark                        Mode  Cnt   Score        Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   200,715 ±   18,103  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10   300,019 ±    8,751  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   347,616 ±  130,348  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10   352,791 ±  105,337  us/op
 2. CharStreams (guava)                         avgt   10   420,137 ±   59,877  us/op
 9. BufferedReader (JDK)                        avgt   10   632,028 ±   17,002  us/op
 5. parallel Stream Api (Java 8)                avgt   10   662,999 ±   46,199  us/op
 4. Stream Api (Java 8)                         avgt   10   701,269 ±   82,296  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   740,837 ±    5,613  us/op
 3. Scanner (JDK)                               avgt   10   751,417 ±   62,026  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10  2919,350 ± 1101,942  us/op

Graphes (tests de performance en fonction de la longueur du flux d'entrée dans le système Windows 7)
 enter image description here

Test de performance (temps moyen) en fonction de la longueur du flux d'entrée dans le système Windows 7:

 length  182    546     1092    3276    9828    29484   58968

 test8  0.38    0.938   1.868   4.448   13.412  36.459  72.708
 test4  2.362   3.609   5.573   12.769  40.74   81.415  159.864
 test5  3.881   5.075   6.904   14.123  50.258  129.937 166.162
 test9  2.237   3.493   5.422   11.977  45.98   89.336  177.39
 test6  1.261   2.12    4.38    10.698  31.821  86.106  186.636
 test7  1.601   2.391   3.646   8.367   38.196  110.221 211.016
 test1  1.529   2.381   3.527   8.411   40.551  105.16  212.573
 test3  3.035   3.934   8.606   20.858  61.571  118.744 235.428
 test2  3.136   6.238   10.508  33.48   43.532  118.044 239.481
 test10 1.593   4.736   7.527   20.557  59.856  162.907 323.147
 test11 3.913   11.506  23.26   68.644  207.591 600.444 1211.545
1964
Viacheslav Vedenin

Apache Commons permet:

String myString = IOUtils.toString(myInputStream, "UTF-8");

Bien sûr, vous pouvez choisir d’autres encodages de caractères en plus de UTF-8.

Voir aussi: ( documentation )

810
Chinnery

Compte tenu du fichier, il faut d’abord obtenir une instance Java.io.Reader. Cela peut ensuite être lu et ajouté à une StringBuilder (nous n'avons pas besoin de StringBuffer si nous n'y avons pas accès, et StringBuilder est plus rapide). L'astuce ici est que nous travaillons par blocs et que, par conséquent, nous n'avons pas besoin d'autres flux de mise en mémoire tampon. La taille de bloc est paramétrée pour l'optimisation des performances d'exécution.

public static String Slurp(final InputStream is, final int bufferSize) {
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    try (Reader in = new InputStreamReader(is, "UTF-8")) {
        for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
                break;
            out.append(buffer, 0, rsz);
        }
    }
    catch (UnsupportedEncodingException ex) {
        /* ... */
    }
    catch (IOException ex) {
        /* ... */
    }
    return out.toString();
}
275
Paul de Vrieze

Utilisation:

InputStream in = /* Your InputStream */;
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;

while ((read=br.readLine()) != null) {
    //System.out.println(read);
    sb.append(read);
}

br.close();
return sb.toString();
232
sampathpremarathna

Si vous utilisez Google Collections/Guava, vous pouvez effectuer les opérations suivantes:

InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);

Notez que le second paramètre (c'est-à-dire Charsets.UTF_8) pour la variable InputStreamReader n'est pas nécessaire, mais c'est généralement une bonne idée de spécifier le codage si vous le connaissez (ce que vous devriez!).

163
Sakuraba

Ceci est ma solution pure Java et Android, et cela fonctionne bien ...

public String readFullyAsString(InputStream inputStream, String encoding)
        throws IOException {
    return readFully(inputStream).toString(encoding);
}

public byte[] readFullyAsBytes(InputStream inputStream)
        throws IOException {
    return readFully(inputStream).toByteArray();
}

private ByteArrayOutputStream readFully(InputStream inputStream)
        throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        baos.write(buffer, 0, length);
    }
    return baos;
}
111
TacB0sS

Voici la solution la plus élégante en Java pur (sans bibliothèque) que j'ai trouvée après quelques expériences:

public static String fromStream(InputStream in) throws IOException
{
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder out = new StringBuilder();
    String newLine = System.getProperty("line.separator");
    String line;
    while ((line = reader.readLine()) != null) {
        out.append(line);
        out.append(newLine);
    }
    return out.toString();
}
57
Drew Noakes

Utilisation:

import Java.io.BufferedInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.InputStream;
import Java.io.IOException;

public static String readInputStreamAsString(InputStream in)
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }
    return buf.toString();
}
57
Jon Moore

Pour être complet, voici la solution Java 9:

public static String toString(InputStream input) throws IOException {
    return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}

Le readAllBytes est actuellement dans la base de code principale du JDK 9, il est donc susceptible de figurer dans la version. Vous pouvez l'essayer dès maintenant en utilisant le JDK 9 snapshot builds .

47
Tagir Valeev

J'utiliserais quelques astuces Java 8.

public static String streamToString(final InputStream inputStream) throws Exception {
    // buffering optional
    try
    (
        final BufferedReader br
           = new BufferedReader(new InputStreamReader(inputStream))
    ) {
        // parallel optional
        return br.lines().parallel().collect(Collectors.joining("\n"));
    } catch (final IOException e) {
        throw new RuntimeException(e);
        // whatever.
    }
}

Essentiellement les mêmes que d'autres réponses, à l'exception de plus succinctes.

35
Simon Kuang

J'ai fait un repère sur 14 réponses distinctes ici (désolé de ne pas fournir de crédits mais il y a trop de doublons).

Le résultat est très surprenant. Il s'avère que Apache IOUtils est la solution la plus lente et ByteArrayOutputStream est la solution la plus rapide:

Alors d'abord, voici la meilleure méthode:

public String inputStreamToString(InputStream inputStream) throws IOException {
    try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }

        return result.toString(UTF_8);
    }
}

Résultats de référence, de 20 Mo aléatoires sur 20 cycles

Temps en millisecondes

  • ByteArrayOutputStreamTest: 194
  • NioStream: 198
  • Java9ISTransferTo: 201
  • Java9ISReadAllBytes: 205
  • BufferedInputStreamVsByteArrayOutputStream: 314
  • ApacheStringWriter2: 574
  • GuavaCharStreams: 589
  • ScannerReaderNoNextTest: 614
  • ScannerReader: 633
  • ApacheStringWriter: 1544
  • StreamApi: Erreur
  • ParallelStreamApi: Erreur
  • BufferReaderTest: Erreur
  • InputStreamAndStringBuilder: Erreur

Code source de référence

import com.google.common.io.CharStreams;
import org.Apache.commons.io.IOUtils;

import Java.io.*;
import Java.nio.ByteBuffer;
import Java.nio.channels.Channels;
import Java.nio.channels.ReadableByteChannel;
import Java.nio.channels.WritableByteChannel;
import Java.util.Arrays;
import Java.util.List;
import Java.util.Random;
import Java.util.stream.Collectors;

/**
 * Created by Ilya Gazman on 2/13/18.
 */
public class InputStreamToString {


    private static final String UTF_8 = "UTF-8";

    public static void main(String... args) {
        log("App started");
        byte[] bytes = new byte[1024 * 1024];
        new Random().nextBytes(bytes);
        log("Stream is ready\n");

        try {
            test(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void test(byte[] bytes) throws IOException {
        List<Stringify> tests = Arrays.asList(
                new ApacheStringWriter(),
                new ApacheStringWriter2(),
                new NioStream(),
                new ScannerReader(),
                new ScannerReaderNoNextTest(),
                new GuavaCharStreams(),
                new StreamApi(),
                new ParallelStreamApi(),
                new ByteArrayOutputStreamTest(),
                new BufferReaderTest(),
                new BufferedInputStreamVsByteArrayOutputStream(),
                new InputStreamAndStringBuilder(),
                new Java9ISTransferTo(),
                new Java9ISReadAllBytes()
        );

        String solution = new String(bytes, "UTF-8");

        for (Stringify test : tests) {
            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
                String s = test.inputStreamToString(inputStream);
                if (!s.equals(solution)) {
                    log(test.name() + ": Error");
                    continue;
                }
            }
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < 20; i++) {
                try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
                    test.inputStreamToString(inputStream);
                }
            }
            log(test.name() + ": " + (System.currentTimeMillis() - startTime));
        }
    }

    private static void log(String message) {
        System.out.println(message);
    }

    interface Stringify {
        String inputStreamToString(InputStream inputStream) throws IOException;

        default String name() {
            return this.getClass().getSimpleName();
        }
    }

    static class ApacheStringWriter implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            StringWriter writer = new StringWriter();
            IOUtils.copy(inputStream, writer, UTF_8);
            return writer.toString();
        }
    }

    static class ApacheStringWriter2 implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return IOUtils.toString(inputStream, UTF_8);
        }
    }

    static class NioStream implements Stringify {

        @Override
        public String inputStreamToString(InputStream in) throws IOException {
            ReadableByteChannel channel = Channels.newChannel(in);
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 16);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            WritableByteChannel outChannel = Channels.newChannel(bout);
            while (channel.read(byteBuffer) > 0 || byteBuffer.position() > 0) {
                byteBuffer.flip();  //make buffer ready for write
                outChannel.write(byteBuffer);
                byteBuffer.compact(); //make buffer ready for reading
            }
            channel.close();
            outChannel.close();
            return bout.toString(UTF_8);
        }
    }

    static class ScannerReader implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            Java.util.Scanner s = new Java.util.Scanner(is).useDelimiter("\\A");
            return s.hasNext() ? s.next() : "";
        }
    }

    static class ScannerReaderNoNextTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            Java.util.Scanner s = new Java.util.Scanner(is).useDelimiter("\\A");
            return s.next();
        }
    }

    static class GuavaCharStreams implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            return CharStreams.toString(new InputStreamReader(
                    is, UTF_8));
        }
    }

    static class StreamApi implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.joining("\n"));
        }
    }

    static class ParallelStreamApi implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new BufferedReader(new InputStreamReader(inputStream)).lines()
                    .parallel().collect(Collectors.joining("\n"));
        }
    }

    static class ByteArrayOutputStreamTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) != -1) {
                    result.write(buffer, 0, length);
                }

                return result.toString(UTF_8);
            }
        }
    }

    static class BufferReaderTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            String newLine = System.getProperty("line.separator");
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder result = new StringBuilder(UTF_8);
            String line;
            boolean flag = false;
            while ((line = reader.readLine()) != null) {
                result.append(flag ? newLine : "").append(line);
                flag = true;
            }
            return result.toString();
        }
    }

    static class BufferedInputStreamVsByteArrayOutputStream implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            int result = bis.read();
            while (result != -1) {
                buf.write((byte) result);
                result = bis.read();
            }

            return buf.toString(UTF_8);
        }
    }

    static class InputStreamAndStringBuilder implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            int ch;
            StringBuilder sb = new StringBuilder(UTF_8);
            while ((ch = inputStream.read()) != -1)
                sb.append((char) ch);
            return sb.toString();
        }
    }

    static class Java9ISTransferTo implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            inputStream.transferTo(bos);
            return bos.toString(UTF_8);
        }
    }

    static class Java9ISReadAllBytes implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new String(inputStream.readAllBytes(), UTF_8);
        }
    }

}
33
Ilya Gazman

J'ai fait des tests de chronométrage, car le temps compte toujours.

J'ai essayé d'obtenir la réponse dans un String 3 différentes manières. (indiqué ci-dessous)
J'ai laissé de côté les blocs try/catch pour améliorer la lisibilité.

Pour donner un contexte, c'est le code précédent pour les 3 approches:

   String response;
   String url = "www.blah.com/path?key=value";
   GetMethod method = new GetMethod(url);
   int status = client.executeMethod(method);

1)

 response = method.getResponseBodyAsString();

2)

InputStream resp = method.getResponseBodyAsStream();
InputStreamReader is=new InputStreamReader(resp);
BufferedReader br=new BufferedReader(is);
String read = null;
StringBuffer sb = new StringBuffer();
while((read = br.readLine()) != null) {
    sb.append(read);
}
response = sb.toString();

3)

InputStream iStream  = method.getResponseBodyAsStream();
StringWriter writer = new StringWriter();
IOUtils.copy(iStream, writer, "UTF-8");
response = writer.toString();

Ainsi, après avoir exécuté 500 tests sur chaque approche avec les mêmes données de demande/réponse, voici les chiffres. Encore une fois, ce sont mes conclusions et vos conclusions peuvent ne pas être exactement les mêmes, mais j'ai écrit ceci pour donner une indication aux autres des différences d'efficacité de ces approches.

Rangs:
Approche # 1
Approche n ° 3 - 2,6% moins rapide que la n ° 1
Approche n ° 2 - 4,3% moins rapide que la n ° 1

Chacune de ces approches est une solution appropriée pour récupérer une réponse et en créer une chaîne.

29
Brett Holt

Solution Java pure utilisant Stream s, fonctionne depuis Java 8.

import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.util.stream.Collectors;

// ...
public static String inputStreamToString(InputStream is) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
        return br.lines().collect(Collectors.joining(System.lineSeparator()));
    }
}

Comme mentionné par Christoffer Hammarström ci-dessous autre réponse il est plus sûr de spécifier explicitement le Charset . C'est à dire. Le constructeur InputStreamReader peut être modifié comme suit:

new InputStreamReader(is, Charset.forName("UTF-8"))
27
czerny

Voici la réponse plus ou moins sampath, nettoyée un peu et représentée en fonction:

String streamToString(InputStream in) throws IOException {
  StringBuilder out = new StringBuilder();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  for(String line = br.readLine(); line != null; line = br.readLine()) 
    out.append(line);
  br.close();
  return out.toString();
}
23
TKH

Si vous vous sentiez aventureux, vous pourriez mélanger Scala et Java et vous retrouver avec ceci:

scala.io.Source.fromInputStream(is).mkString("")

Le mélange de code et de bibliothèques Java et Scala présente des avantages.

Voir la description complète ici: Méthode idiomatique pour convertir un InputStream en String dans Scala

21
Jack

Si vous ne pouvez pas utiliser Commons IO (FileUtils/IOUtils/CopyUtils), voici un exemple d'utilisation de BufferedReader pour lire le fichier ligne par ligne:

public class StringFromFile {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFile.class.getResourceAsStream("file.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(is/*, "UTF-8"*/));
        final int CHARS_PER_PAGE = 5000; //counting spaces
        StringBuilder builder = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(String line=br.readLine(); line!=null; line=br.readLine()) {
                builder.append(line);
                builder.append('\n');
            }
        } 
        catch (IOException ignore) { }

        String text = builder.toString();
        System.out.println(text);
    }
}

Ou si vous voulez une vitesse brute, je proposerais une variante de ce que Paul de Vrieze a suggéré (ce qui évite d'utiliser un StringWriter (qui utilise un StringBuffer en interne):

public class StringFromFileFast {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFileFast.class.getResourceAsStream("file.txt");
        InputStreamReader input = new InputStreamReader(is/*, "UTF-8"*/);
        final int CHARS_PER_PAGE = 5000; //counting spaces
        final char[] buffer = new char[CHARS_PER_PAGE];
        StringBuilder output = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(int read = input.read(buffer, 0, buffer.length);
                    read != -1;
                    read = input.read(buffer, 0, buffer.length)) {
                output.append(buffer, 0, read);
            }
        } catch (IOException ignore) { }

        String text = output.toString();
        System.out.println(text);
    }
}
18
DJDaveMark

Ceci est une réponse adaptée de org.Apache.commons.io.IOUtilscode source , pour ceux qui souhaitent avoir l’implémentation Apache mais ne veulent pas de la bibliothèque entière.

private static final int BUFFER_SIZE = 4 * 1024;

public static String inputStreamToString(InputStream inputStream, String charsetName)
        throws IOException {
    StringBuilder builder = new StringBuilder();
    InputStreamReader reader = new InputStreamReader(inputStream, charsetName);
    char[] buffer = new char[BUFFER_SIZE];
    int length;
    while ((length = reader.read(buffer)) != -1) {
        builder.append(buffer, 0, length);
    }
    return builder.toString();
}
17
Dreaming in Code

Assurez-vous de fermer les flux à la fin si vous utilisez Stream Readers

private String readStream(InputStream iStream) throws IOException {
    //build a Stream Reader, it can read char by char
    InputStreamReader iStreamReader = new InputStreamReader(iStream);
    //build a buffered Reader, so that i can read whole line at once
    BufferedReader bReader = new BufferedReader(iStreamReader);
    String line = null;
    StringBuilder builder = new StringBuilder();
    while((line = bReader.readLine()) != null) {  //Read till end
        builder.append(line);
        builder.append("\n"); // append new line to preserve lines
    }
    bReader.close();         //close all opened stuff
    iStreamReader.close();
    //iStream.close(); //EDIT: Let the creator of the stream close it!
                       // some readers may auto close the inner stream
    return builder.toString();
}

EDIT: Sur JDK 7+, vous pouvez utiliser la construction try-with-resources.

/**
 * Reads the stream into a string
 * @param iStream the input stream
 * @return the string read from the stream
 * @throws IOException when an IO error occurs
 */
private String readStream(InputStream iStream) throws IOException {

    //Buffered reader allows us to read line by line
    try (BufferedReader bReader =
                 new BufferedReader(new InputStreamReader(iStream))){
        StringBuilder builder = new StringBuilder();
        String line;
        while((line = bReader.readLine()) != null) {  //Read till end
            builder.append(line);
            builder.append("\n"); // append new line to preserve lines
        }
        return builder.toString();
    }
}
16
Thamme Gowda

Voici la méthode complète pour convertir InputStream en String sans utiliser de bibliothèque tierce. Utilisez StringBuilder pour un environnement à un seul thread, sinon utilisez StringBuffer

public static String getString( InputStream is) throws IOException {
    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = is.read()) != -1)
        sb.append((char)ch);
    return sb.toString();
}
15
laksys

Voici comment le faire en utilisant uniquement le JDK en utilisant des tampons de tableau d'octets. C’est en fait ainsi que fonctionnent toutes les méthodes commons-io IOUtils.copy(). Vous pouvez remplacer byte[] par char[] si vous copiez à partir d'une Reader au lieu d'une InputStream.

import Java.io.ByteArrayOutputStream;
import Java.io.InputStream;

...

InputStream is = ....
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
byte[] buffer = new byte[8192];
int count = 0;
try {
  while ((count = is.read(buffer)) != -1) {
    baos.write(buffer, 0, count);
  }
}
finally {
  try {
    is.close();
  }
  catch (Exception ignore) {
  }
}

String charset = "UTF-8";
String inputStreamAsString = baos.toString(charset);
14
Matt Shannon

Un autre, pour tous les utilisateurs de Spring:

import Java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;

public String convertStreamToString(InputStream is) throws IOException { 
    return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}

Les méthodes utilitaires dans org.springframework.util.StreamUtils sont similaires à celles de FileCopyUtils, mais elles laissent le flux ouvert lorsque vous avez terminé.

12
James

Utilisez le Java.io.InputStream.transferTo (OutputStream) pris en charge en Java 9 et le ByteArrayOutputStream.toString (String) qui prend le nom du jeu de caractères:

public static String gobble(InputStream in, String charsetName) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    in.transferTo(bos);
    return bos.toString(charsetName);
}
12
jmehrens

Les utilisateurs de Kotlin font simplement:

println(InputStreamReader(is).readText())

tandis que 

readText()

est la méthode d’extension intégrée à la bibliothèque standard Kotlin.

11
Alex

Celui-ci est gentil parce que:

  • Sécurité des mains le jeu de caractères.
  • Vous contrôlez la taille du tampon de lecture.
  • Vous pouvez configurer la longueur du constructeur et ne pas être exactement.
  • Est libre de dépendances de la bibliothèque.
  • Est pour Java 7 ou supérieur.

Qu'est-ce que le pour?

public static String convertStreamToString(InputStream is) {
   if (is == null) return null;
   StringBuilder sb = new StringBuilder(2048); // Define a size if you have an idea of it.
   char[] read = new char[128]; // Your buffer size.
   try (InputStreamReader ir = new InputStreamReader(is, StandardCharsets.UTF_8)) {
     for (int i; -1 != (i = ir.read(read)); sb.append(read, 0, i));
   } catch (Throwable t) {}
   return sb.toString();
}
9
Daniel De León

Le moyen le plus simple dans JDK consiste à utiliser les extraits de code suivants. 

String convertToString(InputStream in){
    String resource = new Scanner(in).useDelimiter("\\Z").next();
    return resource;
}
7
Raghu K Nair

Voici ma solution basée sur Java 8, qui utilise la new Stream API pour collecter toutes les lignes d'une InputStream:

public static String toString(InputStream inputStream) {
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(inputStream));
    return reader.lines().collect(Collectors.joining(
        System.getProperty("line.separator")));
}
6
Christian Rädel

Dans Groovy

inputStream.getText()
5
Snekse

En termes de reduce et concat, il peut être exprimé en Java 8 par:

String fromFile = new BufferedReader(new   
InputStreamReader(inputStream)).lines().reduce(String::concat).get();
5
libnull-dev

J'ai écrit un cours qui ne fait que ça, alors je me suis dit que je le partagerais avec tout le monde. Parfois, vous ne voulez pas ajouter Apache Commons simplement pour une chose, et vous voulez quelque chose de plus bête que Scanner qui n'examine pas le contenu.

L'utilisation est comme suit

// Read from InputStream
String data = new ReaderSink(inputStream, Charset.forName("UTF-8")).drain();

// Read from File
data = new ReaderSink(file, Charset.forName("UTF-8")).drain();

// Drain input stream to console
new ReaderSink(inputStream, Charset.forName("UTF-8")).drainTo(System.out);

Voici le code pour ReaderSink:

import Java.io.*;
import Java.nio.charset.Charset;

/**
 * A simple sink class that drains a {@link Reader} to a {@link String} or
 * to a {@link Writer}.
 *
 * @author Ben Barkay
 * @version 2/20/2014
 */
public class ReaderSink {
    /**
     * The default buffer size to use if no buffer size was specified.
     */
    public static final int DEFAULT_BUFFER_SIZE = 1024;

    /**
     * The {@link Reader} that will be drained.
     */
    private final Reader in;

    /**
     * Constructs a new {@code ReaderSink} for the specified file and charset.
     * @param file      The file to read from.
     * @param charset   The charset to use.
     * @throws FileNotFoundException    If the file was not found on the filesystem.
     */
    public ReaderSink(File file, Charset charset) throws FileNotFoundException {
        this(new FileInputStream(file), charset);
    }

    /**
     * Constructs a new {@code ReaderSink} for the specified {@link InputStream}.
     * @param in        The {@link InputStream} to drain.
     * @param charset   The charset to use.
     */
    public ReaderSink(InputStream in, Charset charset) {
        this(new InputStreamReader(in, charset));
    }

    /**
     * Constructs a new {@code ReaderSink} for the specified {@link Reader}.
     * @param in    The reader to drain.
     */
    public ReaderSink(Reader in) {
        this.in = in;
    }

    /**
     * Drains the data from the underlying {@link Reader}, returning a {@link String} containing
     * all of the read information. This method will use {@link #DEFAULT_BUFFER_SIZE} for
     * its buffer size.
     * @return  A {@link String} containing all of the information that was read.
     */
    public String drain() throws IOException {
        return drain(DEFAULT_BUFFER_SIZE);
    }

    /**
     * Drains the data from the underlying {@link Reader}, returning a {@link String} containing
     * all of the read information.
     * @param bufferSize    The size of the buffer to use when reading.
     * @return  A {@link String} containing all of the information that was read.
     */
    public String drain(int bufferSize) throws IOException {
        StringWriter stringWriter = new StringWriter();
        drainTo(stringWriter, bufferSize);
        return stringWriter.toString();
    }

    /**
     * Drains the data from the underlying {@link Reader}, writing it to the
     * specified {@link Writer}. This method will use {@link #DEFAULT_BUFFER_SIZE} for
     * its buffer size.
     * @param out   The {@link Writer} to write to.
     */
    public void drainTo(Writer out) throws IOException {
        drainTo(out, DEFAULT_BUFFER_SIZE);
    }

    /**
     * Drains the data from the underlying {@link Reader}, writing it to the
     * specified {@link Writer}.
     * @param out           The {@link Writer} to write to.
     * @param bufferSize    The size of the buffer to use when reader.
     */
    public void drainTo(Writer out, int bufferSize) throws IOException {
        char[] buffer = new char[bufferSize];
        int read;
        while ((read = in.read(buffer)) > -1) {
            out.write(buffer, 0, read);
        }
    }
}
4
Ben Barkay

Basé sur la deuxième partie de la réponse acceptée par Apache Commons mais avec le petit espace comblé pour toujours fermer le flux:

    String theString;
    try {
        theString = IOUtils.toString(inputStream, encoding);
    } finally {
        IOUtils.closeQuietly(inputStream);
    }
4
Steve Chambers

Raghu K Nair Était le seul à utiliser un scanner . Le code que j'utilise est un peu différent:

String convertToString(InputStream in){
    Scanner scanner = new Scanner(in)
    scanner.useDelimiter("\\A");

    boolean hasInput = scanner.hasNext();
    if (hasInput) {
        return scanner.next();
    } else {
        return null;
    }

}

A propos des délimiteurs: Comment utiliser un délimiteur dans Java Scanner?

4
Halfacht

Le code ci-dessous a fonctionné pour moi. 

URL url = MyClass.class.getResource("/" + configFileName);
BufferedInputStream bi = (BufferedInputStream) url.getContent();
byte[] buffer = new byte[bi.available() ];
int bytesRead = bi.read(buffer);
String out = new String(buffer);

Notez que, selon la documentation Java, la méthode available() peut ne pas fonctionner avec InputStream mais fonctionne toujours avec BufferedInputStream. Si vous ne souhaitez pas utiliser la méthode available(), nous pouvons toujours utiliser le code ci-dessous.

URL url = MyClass.class.getResource("/" + configFileName);
BufferedInputStream bi = (BufferedInputStream) url.getContent();
File f = new File(url.getPath());
byte[] buffer = new byte[ (int) f.length()];
int bytesRead = bi.read(buffer);
String out = new String(buffer);

Je ne suis pas sûr s'il y aura des problèmes d'encodage. Veuillez commenter, s'il y aura des problèmes avec le code.

4
Anand N

Guava fournit une solution d'auto-fermeture efficace beaucoup plus courte dans le cas où le flux d'entrée provient d'une ressource de classpath (tâche qui semble être populaire):

byte[] bytes = Resources.toByteArray(classLoader.getResource(path));

ou 

String text = Resources.toString(classLoader.getResource(path), StandardCharsets.UTF_8);

Il existe également le concept général de ByteSource et CharSource qui s’occupe en douceur de l’ouverture et de la fermeture du flux.

Ainsi, par exemple, au lieu d'ouvrir explicitement un petit fichier pour en lire le contenu:

String content = Files.asCharSource(new File("robots.txt"), StandardCharsets.UTF_8).read();
byte[] data = Files.asByteSource(new File("favicon.ico")).read();

ou juste

String content = Files.toString(new File("robots.txt"), StandardCharsets.UTF_8);
byte[] data = Files.toByteArray(new File("favicon.ico"));
4
Vadzim
public String read(InputStream in) throws IOException {
    try (BufferedReader buffer = new BufferedReader(new InputStreamReader(in))) {
        return buffer.lines().collect(Collectors.joining("\n"));
    }
}
3
Hao Zheng

Avec Okio:

String result = Okio.buffer(Okio.source(inputStream)).readUtf8();
3
drakeet

JDK 7/8 réponse qui ferme le flux et lève toujours une exception IOException:

StringBuilder build = new StringBuilder();
byte[] buf = new byte[1024];
int length;
try (InputStream is = getInputStream()) {
  while ((length = is.read(buf)) != -1) {
    build.append(new String(buf, 0, length));
  }
}
3
Brian Pontarelli

Vous pouvez utiliser Apache Commons.

Dans IOUtils, vous pouvez trouver la méthode toString avec trois implémentations utiles.

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input, String encoding)
            throws IOException {
        return toString(input, Charsets.toCharset(encoding));
}
3
Rys
InputStream is = Context.openFileInput(someFileName); // whatever format you have

ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] b = new byte[8192];
for (int bytesRead; (bytesRead = is.read(b)) != -1;) {
    bos.write(b, 0, bytesRead);
}

String output = bos.toString(someEncoding);
3
Vaishali Sutariya
InputStreamReader i = new InputStreamReader(s);
BufferedReader str = new BufferedReader(i);
String msg = str.readLine();
System.out.println(msg);

Voici s votre objet InputStream qui sera converti en String 

3
Omkar Khot

Essayez ces 4 déclarations ..

Selon le point rappelé par Fred, il n'est pas recommandé d'ajouter un opérateur String avec += car chaque fois qu'un nouveau char est ajouté à l'objet String existant, créant à nouveau un nouvel objet String et attribuant son adresse à st tandis que l'ancien objet st devient .

public String convertStreamToString(InputStream is)
{
    int k;
    StringBuffer sb=new StringBuffer();
    while((k=fin.read()) != -1)
    {
        sb.append((char)k);
    }
    return sb.toString();
}

Non recommandé, mais c'est aussi un moyen

public String convertStreamToString(InputStream is) { 
    int k;
    String st="";
    while((k=is.read()) != -1)
    {
        st+=(char)k;
    }
    return st;
}
3
JavaTechnical

Eh bien, vous pouvez le programmer vous-même ... Ce n'est pas compliqué ...

String Inputstream2String (InputStream is) throws IOException
    {
        final int PKG_SIZE = 1024;
        byte[] data = new byte [PKG_SIZE];
        StringBuilder buffer = new StringBuilder(PKG_SIZE * 10);
        int size;

        size = is.read(data, 0, data.length);
        while (size > 0)
        {
            String str = new String(data, 0, size);
            buffer.append(str);
            size = is.read(data, 0, data.length);
        }
        return buffer.toString();
    }
3
Victor

Ce qui suit ne traite pas de la question initiale, mais plutôt de certaines des réponses.

Plusieurs réponses suggèrent des boucles de la forme

String line = null;
while((line = reader.readLine()) != null) {
  // ...
}

ou

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    // ...
}

La première forme pollue l'espace de noms de la portée englobante en déclarant une variable "read" dans la portée englobante qui ne sera utilisée pour rien en dehors de la boucle for. Le second formulaire duplique l'appel readline ().

Voici une manière bien plus propre d’écrire ce type de boucle en Java. Il s'avère que la première clause d'une boucle for ne nécessite pas de valeur d'initialiseur réelle. Cela permet de conserver l'étendue de la variable "line" dans le corps de la boucle for. Beaucoup plus élégant! Je n'ai vu personne utiliser ce formulaire où que ce soit (je l'ai découvert au hasard il y a un jour, il y a des années), mais je l'utilise tout le temps.

for (String line; (line = reader.readLine()) != null; ) {
    //...
}
2
Luke Hutchison

Vous pouvez utiliser Cactoos :

String text = new TextOf(inputStream).asString();

Le codage UTF-8 est celui par défaut. Si vous avez besoin d'un autre:

String text = new TextOf(inputStream, "UTF-16").asString();
2
yegor256

Note: Ce n'est probablement pas une bonne idée. Cette méthode utilise la récursivité et frappe donc très rapidement une StackOverflowError:

public String read (InputStream is) {
    byte next = is.read();
    return next == -1 ? "" : next + read(is); // Recursive part: reads next byte recursively
}

S'il vous plaît, n'enregistrez pas cela simplement parce que c'est un mauvais choix à utiliser; c'était surtout créatif :)

2
HyperNeutrino

Utilisation:

String theString = IOUtils.toString(inputStream, encoding);
1
Avinash

Cette solution à cette question n'est pas la plus simple, mais comme les flux et canaux NIO n'ont pas été mentionnés, voici une version qui utilise les canaux NIO et un ByteBuffer pour convertir un flux en chaîne.

public static String streamToStringChannel(InputStream in, String encoding, int bufSize) throws IOException {
    ReadableByteChannel channel = Channels.newChannel(in);
    ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    WritableByteChannel outChannel = Channels.newChannel(bout);
    while (channel.read(byteBuffer) > 0 || byteBuffer.position() > 0) {
        byteBuffer.flip();  //make buffer ready for write
        outChannel.write(byteBuffer);
        byteBuffer.compact(); //make buffer ready for reading
    }
    channel.close();
    outChannel.close();
    return bout.toString(encoding);
}

Voici un exemple d'utilisation:

try (InputStream in = new FileInputStream("/tmp/large_file.xml")) {
    String x = streamToStringChannel(in, "UTF-8", 1);
    System.out.println(x);
}

Les performances de cette méthode devraient être bonnes pour les gros fichiers.

1
gil.fernandes
InputStream  inputStream = null;
BufferedReader bufferedReader = null;
try {
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    String stringBuilder = new StringBuilder();
    String content;
    while((content = bufferedReader.readLine()) != null){
        stringBuilder.append(content);
    }
    System.out.println("content of file::" + stringBuilder.toString());
}
catch (IOException e) {
            e.printStackTrace();
        }finally{           
            if(bufferedReader != null){
                try{
                    bufferedReader.close();
                }catch(IoException ex){
                   ex.printStackTrace();
            }
1
Harsh

Méthode pour convertir inputStream en chaîne

public static String getStringFromInputStream(InputStream inputStream) {

    BufferedReader bufferedReader = null;
    StringBuilder stringBuilder = new StringBuilder();
    String line;

    try {
        bufferedReader = new BufferedReader(new InputStreamReader(
                inputStream));
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
        }
    } catch (IOException e) {
        logger.error(e.getMessage());
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }
    return stringBuilder.toString();
}
1
Jitender Chahar

Ce fragment de code a été trouvé dans\sdk\samples\Android-19\connectivity\NetworkConnect\NetworkConnectSample\src\main\Java\com\exemple\Android\networkconnect\MainActivity.Java, sous licence Apache, Version 2.0 et écrit par Google .

/** Reads an InputStream and converts it to a String.
 * @param stream InputStream containing HTML from targeted site.
 * @param len Length of string that this method returns.
 * @return String concatenated according to len parameter.
 * @throws Java.io.IOException
 * @throws Java.io.UnsupportedEncodingException
 */
private String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
    Reader reader = null;
    reader = new InputStreamReader(stream, "UTF-8");
    char[] buffer = new char[len];
    reader.read(buffer);
    return new String(buffer);
}
1
Fred

String resultString = IOUtils.toString (userInputStream, "UTF-8");

0
Akash

J'ai créé ce code et cela fonctionne. Il n'y a pas de plug-in externe requis.

Il existe des chaînes de conversion en flux et de flux en chaînes ...

import Java.io.ByteArrayInputStream;
import Java.io.InputStream;

public class STRINGTOSTREAM {

    public static void main(String[] args)
    {
        String text = "Hello Bhola..!\nMy Name Is Kishan ";

        InputStream strm = new ByteArrayInputStream(text.getBytes());    // Convert String to Stream

        String data = streamTostring(strm);

        System.out.println(data);
    }

    static String streamTostring(InputStream stream)
    {
        String data = "";

        try
        {
            StringBuilder stringbuld = new StringBuilder();
            int i;
            while ((i=stream.read())!=-1)
            {
                stringbuld.append((char)i);
            }
            data = stringbuld.toString();
        }
        catch(Exception e)
        {
            data = "No data Streamed.";
        }
        return data;
    }
0
13hola

Je suggère le StringWriter class pour ce problème.

StringWriter wt= new StringWriter();
IOUtils.copy(inputStream, wt, encoding);
String st= wt.toString();
0
Hasee Amarathunga

Vous pouvez également obtenir InputStream à partir d'un chemin de ressource spécifié:

public static InputStream getResourceAsStream(String path)
{
    InputStream myiInputStream = ClassName.class.getResourceAsStream(path);
    if (null == myiInputStream)
    {
        mylogger.info("Can't find path = ", path);
    }

    return myiInputStream;
}

Pour obtenir InputStream à partir d'un chemin spécifique:

public static URL getResource(String path)
{
    URL myURL = ClassName.class.getResource(path);
    if (null == myURL)
    {
        mylogger.info("Can't find resource path = ", path);
    }
    return myURL;
}
0
Ravi