2011-04-29 39 views
16

Tôi đã lấy đoạn trích này ra khỏi web. Nhưng có vẻ như bị giới hạn ở 4096 byte và IMO khá xấu xí. Có ai biết cách tiếp cận tốt hơn không? Tôi đang thực sự sử dụng Groovy btw ...Chuyển đổi luồng thành chuỗi Java/Groovy

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:

Tôi tìm thấy một giải pháp tốt hơn trong Groovy:

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

Trả lời

36

Một số câu trả lời tốt và nhanh. Tuy nhiên tôi nghĩ tốt nhất là Groovy đã thêm phương thức "getText" vào InputStream. Vì vậy, tất cả những gì tôi phải làm là stream.text. Và kêu gọi tốt trên bình luận 4096.

+2

Vì vậy, bạn đã kiểm tra các tài liệu _after_ yêu cầu? Ít nhất bạn có thể dán một ví dụ về việc sử dụng nó. – Anon

+1

Tôi tiếp tục chăm sóc tôi hỏi tất nhiên, tôi không thấy phương pháp .text lúc đầu. Đây là đoạn mã: InputStream exportTemplateStream = getClass(). GetClassLoader().getResourceAsStream ("export.template") khẳng định exportTemplateStream: "[export.template stream] không tìm thấy tài nguyên" Chuỗi exportTemplate = exportTemplateStream.text –

+0

đủ công bằng. Nhưng như tôi đã nói với những người khác: sử dụng các biến thể mà có một bộ ký tự rõ ràng - bộ ký tự mặc định là hiếm khi những gì bạn muốn. – Anon

4

Bạn có thể làm điều đó khá dễ dàng bằng cách sử dụng lớp Scanner:

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

Bạn cần phải vượt qua bộ ký tự hoặc bạn sẽ gặp phải lỗi khó chẩn đoán. – Anon

+0

@Anon, mã này có thể có nhiều lỗi trong đó. Mã chỉ được trình bày làm ví dụ; không được sử dụng trong sản xuất. – jjnguy

+1

@jinguy - không trình bày mã lỗi "cải thiện internet"? Hoặc chỉ cần thêm vào đại diện? – Anon

4

Nó đọc đầu vào theo khối 4096 byte (4KB), nhưng kích thước của chuỗi thực tế không giới hạn ed vì nó tiếp tục đọc nhiều hơn và thêm nó vào SringBuffer.

7

Hãy thử IOUtils từ Apache Commons:

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

Đó đoạn mã có một lỗi: nếu đầu vào sử dụng một mã hóa ký tự đa byte, có một cơ hội tốt mà một nhân vật duy nhất sẽ kéo dài hai lần đọc (và không được có thể chuyển đổi). Và nó cũng có bán lỗi mà nó dựa trên mã hóa mặc định của nền tảng.

Thay vào đó, hãy sử dụng Jakarta Commons IO. Cụ thể, phiên bản IOUtils.toString() mất InputStream và áp dụng mã hóa cho nó.

1

Đối với người đánh giá tương lai có vấn đề tương tự, xin lưu ý rằng cả IOUtils từ Apache và phương thức InputStream.getText() của Groovy đều yêu cầu luồng hoàn thành hoặc đóng trước khi trở về. Nếu bạn đang làm việc với một luồng liên tục, bạn sẽ nead để đối phó với ví dụ "xấu xí" mà Phil ban đầu được đăng hoặc làm việc với IO không chặn.

0

Bạn có thể thử một cái gì đó tương tự như sau

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

Đối với Groovy

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

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

The InputStream class reference

Các getText() mà không cần mã hóa, nó sẽ sử dụng mã hóa hệ thống hiện tại, cựu ("UTF-8 ").

Các vấn đề liên quan