Soru Bir InputStream'i bir String'e oku / dönüştür


Eğer bir java.io.InputStream Nesne, bu nesneyi nasıl işlemeli ve nasıl üretmelisiniz? String?


Varsayalım InputStream bu, metin verilerini içerir ve bunu bir Stringörneğin, bunu bir günlük dosyasına yazabilirim.

Almanın en kolay yolu nedir InputStream ve onu bir String?

public String convertStreamToString(InputStream is) { 
    // ???
}

3267
2017-11-21 16:47


Menşei


Çocuğum, kesinlikle Java'ya aşığım, ama bu soru o kadar sık ​​ortaya çıkıyor ki, akarsuların zincirlenmesinin biraz zor olduğunu ve ya yardımcıların çeşitli kombinasyonlar yaratmasını ya da her şeyi yeniden düşünmesini sağladıklarını düşünürdünüz. - Bill K
Bu sorunun yanıtları yalnızca akış içeriğini okumak istiyorsanız işe yarar tamamen (kapalı olana kadar). Bu her zaman amaçlanmadığı için (canlı bir bağlantıya sahip http istekleri kapalı olmaz), bu yöntem bloğu (size içeriği vermez) çağırır. - f1sh
Sen gerek akış için karakter kodlamasını bilmek ve belirtmek veya irade karakter kodlama hatalarına sahip olursunuz, çünkü hangi makinenin / işletim sisteminin / platformunun veya kodunuzun sürümünün üzerinde çalıştığına bağlı olarak rastgele seçilmiş bir kodlama kullanacaksınız. Yani değil Platform varsayılan kodlamasına bağlı olan yöntemleri kullanın. - Christoffer Hammarström
Sadece 9 yıl önce kendi yorumumu ile eğlenmek için, bugünlerde Groovy'nin "String s = new File (" SomeFile.txt "). Text" bir kerede tüm bir dosyayı okumak ve harika çalışıyor. Üretim dışı (komut dosyası) kodlarımda kullanacağım için çok mutluyum ve - dürüstçe kodlama ve son derece uzun dosyalar ile uğraşmanızı zorluyorum java'nın üretim kodu için gerçekten iyi bir fikir olduğunu, bu yüzden de bu amaç için çalışıyor. Groovy, java'nın mükemmel olmadığı hızlı komut dosyaları için çalışır - Sadece iş için doğru aracı kullanın ve her şey yolunda. - Bill K
Sadece basitleştirme: ByteArrayOutputStream outputBytes = new ByteArrayOutputStream();  for(byte[] b = new byte[512]; 0 < inputStream.read(b); outputBytes.write(b));  return new String(outputBytes.toByteArray(), StandardCharsets.UTF_8); - Felypp Oliveira


Cevaplar:


Bunu yapmanın güzel bir yolu kullanmak Apache müşterek  IOUtils kopyalamak InputStream içine StringWriter... gibi bir şey

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

ya da

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

Alternatif olarak, kullanabilirsiniz ByteArrayOutputStream Akışlarınızı ve Yazarlarınızı karıştırmak istemiyorsanız


2048
2017-11-21 16:54



FileInputstream ile deneyin "До_свидания" dosya adı (Rus dili) ile dosya adı okumaya çalıştığınızda filenotfound istisna buldum ama sdcard bu dosya adını okumak için kablo değil. - Bhanu Sharma
Android geliştiricileri için, Apache'den IOUtils ile android gelmiyor gibi görünüyor. Yani diğer cevaplara başvurmayı düşünebilirsiniz. - Chris.Zou
Sınırlı bir ayak izi ortamında çalışıyorum, bu yüzden java io / util libs kullanarak aşağıdaki @PavelRepin çözümü daha mantıklı. - James
Bu, bu noktada inanılmaz derecede eski bir sorudur (2008'de sorulmuştur). Daha modern cevapları okumak için zaman ayırmaya değer. Bazıları Java 8 kitaplığından yerel aramalar kullanır. - Shadoninja
Bu cevap çok modası geçmiş ve bu şekilde işaretlenmelidir (ne yazık ki bu mümkün değil atm). - codepleb


İşte sadece standart Java kütüphanesini kullanarak bir yol var (akışın kapalı olmadığını unutmayın, YMMV).

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

Bu hileyi öğrendim "Aptal Tarayıcı hileleri" makale. Çalışmasının nedeni: Tarayıcı akıştaki belirteçleri yineler ve bu durumda "giriş sınırının başlangıcını" (\ A) kullanarak belirteçler ayırırız, böylece akışın tüm içeriği için bize yalnızca bir belirteç verir.

Giriş akışının kodlaması hakkında spesifik olmanız gerekiyorsa, ikinci bağımsız değişkeni Scanner hangi karakter kümesinin kullanılacağını belirleyen kurucu (ör. "UTF-8").

Şapka ucu da gider Jacob Beni bir keresinde söz konusu makaleye yönlendirdi.

DÜZENLENMİŞ: Bir öneri sayesinde Patrickboş bir giriş akışı ile çalışırken işlevi daha sağlam hale getirdi. Bir daha düzenleme: nixed try / catch, Patrick'in yolu daha laconic.


2093
2018-03-26 20:40



Teşekkürler, bu benim versiyonum için giriş akışını kapatan bir sonuncu bloğu ekledim, bu yüzden girişi okumayı bitirdiğinizden beri kullanıcı buna sahip değil. Arayan kodunu önemli ölçüde basitleştirir.
@PavelRepin @Patrick benim durumumda, boş bir inputStream Tarayıcı yapımı sırasında bir NPE'ye neden oldu. Eklemek zorundaydım if (is == null) return ""; yöntemin başlangıcında; Bu cevabın boş inputStreams ile daha iyi başa çıkmak için güncellenmesi gerektiğine inanıyorum. - CFL_Jeff
Java 7 için şunu deneyebilirsiniz: try(java.util.Scanner s = new java.util.Scanner(is)) { return s.useDelimiter("\\A").hasNext() ? s.next() : ""; } - earcam
Ne yazık ki bu çözüm benim temel akış uygulamamda atılan istisnaları yitiriyor ve kaybediyor gibi görünüyor. - Taig
Bilginize, hasNext Konsol giriş akışlarında bloklar (bkz. İşte). (Sadece şu anda bu konuya koştu.) Bu çözüm gayet iyi çalışıyor ... sadece bir kafa. - Ryan


Diğer cevapları özetle, bunu yapmanın 11 ana yolunu buldum (aşağıya bakın). Ve bazı performans testleri yazdım (aşağıdaki sonuçlara bakınız):

Bir InputStream'i bir String'e dönüştürme yolları:

  1. kullanma IOUtils.toString (Apache Utils)

    String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    
  2. kullanma CharStreams (Guava)

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

    Scanner s = new Scanner(inputStream).useDelimiter("\\A");
    String result = s.hasNext() ? s.next() : "";
    
  4. kullanma Akış API'sı (Java 8). Uyarı: Bu çözüm farklı satır sonlarını (örneğin, \r\n) \n.

    String result = new BufferedReader(new InputStreamReader(inputStream))
      .lines().collect(Collectors.joining("\n"));
    
  5. kullanma paralel Akış API'sı (Java 8). Uyarı: Bu çözüm farklı satır sonlarını (örneğin, \r\n) \n.

    String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
       .parallel().collect(Collectors.joining("\n"));
    
  6. kullanma InputStreamReader ve 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. kullanma StringWriter ve IOUtils.copy (Apache Commons)

    StringWriter writer = new StringWriter();
    IOUtils.copy(inputStream, writer, "UTF-8");
    return writer.toString();
    
  8. kullanma ByteArrayOutputStream ve 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. kullanma BufferedReader (JDK). Uyarı: Bu çözüm farklı satır sonlarını (örneğin, \n\r) line.separator sistem özelliği (örneğin, Windows'ta "\ r \ n").

    String newLine = System.getProperty("line.separator");
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder result = new StringBuilder();
    String line; boolean flag = false;
    while ((line = reader.readLine()) != null) {
        result.append(flag? newLine: "").append(line);
        flag = true;
    }
    return result.toString();
    
  10. kullanma BufferedInputStream ve 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. kullanma inputStream.read() ve StringBuilder (JDK). Uyarı: Bu çözüm, örneğin Rusça metinle Unicode ile ilgili sorunlara sahiptir (yalnızca Unicode olmayan metinlerle düzgün çalışır)

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

Uyarı:

  1. Çözümler 4, 5 ve 9, farklı satır sonlarını bire dönüştürür.

  2. Çözüm 11, Unicode metni ile düzgün çalışamaz

Performans testleri

Küçük için performans testleri String (uzunluk = 175), URL’de github (mod = Ortalama Zaman, sistem = Linux, 1.343 puan en iyisidir):

              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

Büyük performans testleri String (uzunluk = 50100), URL’de github (mod = Ortalama Zaman, sistem = Linux, puan 200.715 en iyisidir):

               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

Grafikler (Windows 7 sistemindeki Giriş Akışı uzunluğuna bağlı olarak performans testleri)
enter image description here

Windows 7 sistemindeki Giriş Akışı uzunluğuna bağlı olarak performans testi (Ortalama Süre):

 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

1656
2018-02-17 00:58



"Özet cevap" yazarken, bazı çözümlerin otomatik olarak farklı linebreaks'ları ( \r\n) \n Bazı durumlarda istenmeyen olabilir. Ayrıca gereken ek belleği veya en azından tahsis basıncını görmek güzel olurdu (en azından JMH'yi -prof gc). Gerçekten havalı yazı için grafikleri görmek harika olurdu (aynı giriş boyutu içindeki dize uzunluğuna ve aynı dize uzunluğu içindeki giriş büyüklüğüne bağlı olarak). - Tagir Valeev
Upvoted; en komik şey, sonuçların beklenenden daha fazla olması: standart JDK ve / veya Apache Commons sözdizimsel şeker kullanılmalıdır. - mudasobwa
Muhteşem yazı. Sadece bir şey. Java 8, paralel akışı kullanmanız için sizi kilitlemeye ve beklemeye zorlayacak kaynaklarda (bu giriş akışı gibi) uyarır, böylece paralel akış seçeneği oldukça hantaldır ve buna değmez mi? - mangusbrother
Paralel akış, hat siparişini gerçekten sürdürüyor mu? - Natix
Nedir reset() örnek 11 için? - Rob Stewart


Apache Commons şunları sağlar:

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

Tabii ki, UTF-8'in yanı sıra başka karakter kodlamaları da seçebilirsiniz.

Ayrıca bakınız: (Dokümanlar)


794
2017-12-08 20:13



Ayrıca, varsayılan kodlamayla birlikte bulursanız, yalnızca bir inputStream argümanını alan bir yöntem vardır. - Guillaume Coté
@Guillaume Coté Burada, "java kodunun çalıştırıldığı platforma bağlı olarak, ne olduğundan emin olamayacağınız için" varsayılan kodlamayla iyi "olmamanız gerektiğine inanıyorum. - Per Wiklander
@Per Wiklander Ben seninle aynı fikirde değilim. Tek bir üzerinde çalışacak olan kod, varsayılan kodlamanın iyi olacağından oldukça emin olabilir. Yalnızca yerel dosyayı açan kod için, bunların platform varsayılan kodlaması içinde kodlanmasını istemek makul bir seçenektir. - Guillaume Coté
Googling - <bağımlılık> <groupId> org.apache.commons </ groupId> <artifactId> commons-io </ artifactId> <sürüm> 1.3.2 </ version> </ dependency> 'in zorluklarını herkese kaydetmek için - Chris
Düz dize değişmezini kullanmak yerine karakter kodlaması için apache io (veya diğer) sabitini kullanmak çok az bir gelişme olacaktır. Örneğin: IOUtils.toString (myInputStream, Charsets.UTF_8);


Dosyayı hesaba katarak önce bir java.io.Reader örneği. Bu daha sonra okunabilir ve bir StringBuilder (ihtiyacımız yok StringBuffer Birden fazla iş parçacığında erişmiyorsak ve StringBuilder daha hızlı). Buradaki hilede, bloklarla çalıştığımız ve diğer tamponlama akışlarına ihtiyaç duymadığımız. Blok boyutu, çalışma zamanı performans optimizasyonu için parametrelendirilmiştir.

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();
}

263
2017-08-04 08:29



Bu çözüm, çok baytlı karakterler kullanır. Örnek, tam unicode aralığının (Çince dahil) ifade edilmesine izin veren UTF-8 kodlamasını kullanır. "UTF-8" i başka bir kodlamayla değiştirmek, bu kodlamanın kullanılmasına izin verir. - Paul de Vrieze
@ Kullanıcı1 - Kodlarımdaki kütüphaneleri kullanmayı seviyorum, böylece işimi daha hızlı yapabilirim. Yöneticilerinizin "Vay James" demesi harika bir şey. Bunu nasıl bu kadar hızlı yaptın ?! Ancak, ortak, yeniden kullanılabilir, denenmiş ve test edilmiş bir yardımcı programın dahil edilmesiyle ilgili yanlış fikirlere sahip olduğumuzdan, tekerleği yeniden icat etmek için zaman harcamamız gerektiğinde, projemizin hedeflerini ilerletmek için harcayacağımız zamandan vazgeçiyoruz. Tekerleği yeniden icat ettiğimizde, iki katı kadar çalışıyoruz, ancak bitiş çizgisine daha sonra varıyoruz. Bitiş çizgisine geldiğimizde, bizi tebrik edecek kimse yok. Bir ev inşa ederken, çekiç de yapmayın - jmort253
Üzgünüm, yorumumu tekrar okuduktan sonra, biraz kibirli çıkıyor. Sadece kütüphanelerden kaçınmak için iyi bir nedene sahip olmanın önemli olduğunu düşünüyorum ve bunun sebebi geçerli bir tanesi. - jmort253
@ jmort253 Ürünümüzdeki bazı kitaplıkları birkaç kez güncelledikten sonra performans regresyonunu fark ettik. Neyse ki kendi ürünümüzü üretiyoruz ve satıyoruz, bu yüzden sözüm ona son teslim tarihlerine sahip değiliz. Ne yazık ki, birçok işletim sistemindeki birçok JVM, veri tabanı ve uygulama sunucusunda mevcut olan bir ürün geliştiriyoruz, bu yüzden kötü makineler kullanan kullanıcılar için düşünmeliyiz ... Ve bir dize işlemi optimize ederek% 30-% 40 oranında iyileştirebilir. Ve bir düzeltme: In our product, I even replaced 'biz değiştirdik' olmalı. - coolcfan
@ jmort253 Eğer zaten apache commons kullanıyor olsaydın, bunun için giderdim. Aynı zamanda, kütüphaneleri kullanmanın gerçek bir maliyeti vardır (birçok apache java kütüphanesinde gösterilen bağımlılık çoğalması gibi). Eğer kütüphanenin tek kullanımı bu olsaydı, kütüphaneyi kullanmak çok fazla olurdu. Diğer yandan, kendi arabellek büyüklüğünü / boyutlarını belirleyerek bellek / işlemci kullanım dengesini ayarlayabilirsiniz. - Paul de Vrieze


Buna ne dersin?

InputStream in = / * sizin 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();

226
2017-07-13 15:56



Mesele şu ki, önce çizgiye ayrılıyorsunuz ve sonra onu çözüyorsunuz. Sadece keyfi arabellekleri okumak daha kolay ve hızlıdır. - Paul de Vrieze
Ayrıca, readLine \ n ile \ r arasında ayrım yapmaz, böylece tam akışı yeniden oluşturamazsınız. - María Arias de Reyna Domínguez
@PauldeVrieze kaç satır ve bunları işlemek için ne kadar hızlı ihtiyacınız var !? Herhangi bir performans kaybının küçük olacağına ya da bir keresinde bir dosyaya giriş yaparak ve eski String obj'lerini yok ederken bir arada ele alınabileceğini tahmin ediyorum. - Thufir
çok verimsiz readLine EOL'u aramak için karaktere göre karakter okuyun. Ayrıca, akışta satır sonu yoksa, bu gerçekten anlamlı değildir. - njzk2
Bu en iyi cevap değil, çünkü baytlık olarak bayt değil. Okuyucu yeni satırları seçer, bu yüzden onları korumak için dikkatli olmanız gerekir. - Jeffrey Blattman


Google-Collections / Guava'yı kullanıyorsanız aşağıdakileri yapabilirsiniz:

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

İçin ikinci parametrenin (örn. Charsets.UTF_8) InputStreamReader gerekli değil, ancak bunu biliyorsanız kodlamayı belirtmek iyi bir fikirdir (hangisini yapmalısınız!)


153
2018-05-08 20:24



@harschware: Soru soruldu: "Eğer java.io.InputStream nesnesine sahipseniz, bu nesneyi nasıl işleyeceksiniz ve bir String üretmelisiniz?" Durumda bir akımın zaten mevcut olduğunu varsaydım. - Sakuraba
Cevabınızı çok iyi açıklayamadınız ve gereksiz değişkenler aldınız; user359996 seninle aynı şeyi söyledi ama çok daha net bir şekilde. - Uronym
Guava için +1, giriş akışının kodlamasını belirtmemek için -1. Örneğin. yeni InputStreamReader (akış "UTF-8") - andras
@Chris Noldus Diğer taraftan, bazı insanlar zaten benim gibi projelerinde guava'ya sahipler ve bu çözümün sdk-only versiyonundan daha zarif olduğunu düşünüyorlar. - CorayThan
@Vadzim bu cevap aynıdır - her ikisi de CharStreams.toString'i kullanır - Tom


Bu benim saf Java ve Android çözümüm, iyi çalışıyor ...

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;
}

107
2018-06-10 21:07



Sadece işletme java'da çalışan diğer cevaplarla karşılaştırıldığında Android'de iyi çalışır. - vorrtex
Kısa dizeler için her defasında ".write" satırında OutOfMemory hatası ile Android'de çöktü. - Adam
Kodlamayı ekledim. sadece bir yan not olarak, benim kodumdaki orijinal readFully yöntemi String döndürmez, daha genel amaçlı bir işlev için byte [] döndürür. Kodlama ile yeni String (...) uygulamak, API kullananların sorumluluğundadır! - TacB0sS
Hızlı not: Bunun hafıza ayak izi 2*nn, akışın büyüklüğüne göre, n ByteArrayInputStream otomatik büyüyen sistem. - njzk2
Gereksiz yere hafıza kullanımını ikiye katlar, bu da mobil cihazlarda değerlidir. InputStreamReader kullanmalı ve StringReader'a eklemelisiniz, bayt char dönüştürme, sonuçta toplu olarak değil, anında yapılacaktır. - Oliv


Nasıl hakkında:

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();
}

56
2018-01-01 03:43



Bu yavaş, çünkü bayt byte byte okur. - Daniel De León
@ DanielDeLeón Hayır öyle değil. Bu bir BufferedInputStream. Temel okumalar bir seferde 8192 bayttır. - user207421
@EJP kullanarak daha yavaş buldum BufferedInputStream  ve Bir seferde bir bayt yerine bir bayt dizisi arabelleği okuma. Örnek: 4.56 MiB dosyası okunurken 60 ms vs 60ms. - jk7


İşte bazı deneylerden sonra geldiğim en zarif, saf Java (kütüphane yok) çözümü:

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();
}

55
2017-09-02 11:50



Bir reader.close () eksik yok mu? İdeal olarak deneyin / sonunda ... - Torben Kohlmeier
@TorbenKohlmeier, okuyucular ve tamponların kapatılmasına gerek yok. Sağlanan InputStream Arayan tarafından kapatılmalıdır. - Drew Noakes
Bir CharSet alan InputStreamReader'da daha çok tercih edilen bir kurucu olduğunu belirtmeyi unutmayın. - jontejj
insanlar neden kullanmaya devam ediyor readLine? Eğer satırları kendi başına kullanmazsanız, ne kadar iyi (çok yavaş olmak dışında)? - njzk2
@voho, eğer bir satır bu kadar uzunsa, o zaman bu hatta eşit veya daha büyük olması gereken geri dönüş değerini tahsis etmenin bir yolu yoktur. Büyük dosyalarla uğraşıyorsanız, onları akışlandırmalısınız. Küçük metin dosyalarını belleğe yüklemek için birçok kullanım örneği vardır. - Drew Noakes