2011-12-14 29 views
196

Giả sử tôi vừa sử dụng BufferedInputStream để đọc các byte của tệp văn bản được mã hóa UTF-8 thành một mảng byte. Tôi biết rằng tôi có thể sử dụng các thói quen sau đây để chuyển đổi các byte vào một chuỗi, nhưng là có một cách hiệu quả hơn/thông minh hơn để làm điều này hơn là chỉ iterating thông qua các byte và chuyển đổi mỗi một?UTF-8 byte [] vào chuỗi

public String openFileToString(byte[] _bytes) 
{ 
    String file_string = ""; 

    for(int i = 0; i < _bytes.length; i++) 
    { 
     file_string += (char)_bytes[i]; 
    } 

    return file_string;  
} 
+16

Tại sao không thể bạn chỉ làm điều này 'Chuỗi fileString = new String (_bytes, "UTF-8"); '? – CoolBeans

+1

Ngoài ra, bạn có thể sử dụng BufferedReader để đọc vào một mảng char. –

+0

có thể trùng lặp của [Trong Java, làm cách nào để đọc/chuyển đổi một InputStream thành một chuỗi?] (Http://stackoverflow.com/questions/309424/in-java-how-do-i-read-convert-an- inputstream-to-a-string) – Bruno

Trả lời

402

Nhìn vào constructor cho String

String str = new String(bytes, StandardCharsets.UTF_8); 

Và nếu bạn đang cảm thấy lười biếng, bạn có thể sử dụng thư viện Apache Commons IO để chuyển đổi InputStream vào một String trực tiếp:

String str = IOUtils.toString(inputStream, StandardCharsets.UTF_8); 
+38

Tôi khuyên bạn nên thay thế "UTF-8" bằng StandardCharsets.UTF_8. –

+11

Hoặc [Charsets.UTF_8] của Guava (https://code.google.com/p/guava-libraries/wiki/StringsExplained#Charsets) nếu bạn sử dụng JDK cũ hơn 1.7 – siledh

+4

Sử dụng Charsets.UTF_8 của Guava nếu bạn đang sử dụng Android API dưới 19 quá –

4

Bạn có thể sử dụng hàm tạo String(byte[] bytes) cho điều đó. Xem chi tiết link để biết chi tiết. EDIT Bạn cũng phải xem xét charset mặc định của plateform của bạn theo doc java:

xây dựng một chuỗi mới bằng cách giải mã các mảng nhất định byte sử dụng charset mặc định của nền tảng. Độ dài của chuỗi mới là hàm của bộ ký tự và do đó có thể không bằng độ dài mảng byte. Hành vi của hàm tạo này khi các byte đã cho không hợp lệ trong bộ ký tự mặc định không được chỉ định. Lớp CharsetDecoder nên được sử dụng khi cần kiểm soát nhiều hơn quy trình giải mã .

+1

Và nếu byte của bạn không nằm trong bộ ký tự mặc định của nền tảng, bạn có thể sử dụng phiên bản có đối số 'Charset' thứ hai để đảm bảo chuyển đổi là chính xác. –

+1

@MikeDaniels Thật vậy, tôi không muốn bao gồm tất cả các chi tiết. Chỉ cần chỉnh sửa câu trả lời của tôi – GETah

0

Điều này cũng liên quan đến việc lặp lại, nhưng điều này tốt hơn nhiều so với ghép các chuỗi vì chúng rất rất tốn kém.

public String openFileToString(String fileName) 
{ 
    StringBuilder s = new StringBuilder(_bytes.length); 

    for(int i = 0; i < _bytes.length; i++) 
    { 
     s.append((char)_bytes[i]); 
    } 

    return s.toString();  
} 
+6

chúa yêu quý của tôi. 'Chuỗi str = new String (byte [])' sẽ làm tốt. – zengr

+3

Điều này cải thiện hiệu quả, nhưng nó không giải mã dữ liệu utf8 đúng cách. –

1

String có một constructor mà mất byte [] và charsetname như thông số :)

34

Java String lớp học có một built-in-constructor để chuyển đổi mảng byte thành chuỗi.

byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46}; 

String value = new String(byteArray, "UTF-8"); 
+3

Bạn đang thiếu bộ ký tự ... không hoạt động. – CoolBeans

6

Để chuyển đổi dữ liệu utf-8, bạn không thể giả định tương ứng 1-1 giữa byte và ký tự. Hãy thử điều này:

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

(. Bah tôi thấy tôi cách để làm chậm trong đánh nút trả lời của bạn những bài viết.)

Để đọc toàn bộ tập tin như một String, làm một cái gì đó như thế này:

public String openFileToString(String fileName) throws IOException 
{ 
    InputStream is = new BufferedInputStream(new FileInputStream(fileName)); 

    try { 
     InputStreamReader rdr = new InputStreamReader(is, "UTF-8"); 
     StringBuilder contents = new StringBuilder(); 
     char[] buff = new char[4096]; 
     int len = rdr.read(buff); 
     while (len >= 0) { 
      contents.append(buff, 0, len); 
     } 
     return buff.toString(); 
    } finally { 
     try { 
      is.close(); 
     } catch (Exception e) { 
      // log error in closing the file 
     } 
    } 
} 
+0

Có câu hỏi này đã kết thúc bằng _eck wreck_. – CoolBeans

+0

_Tôi là cách để làm chậm việc nhấn nút Đăng câu trả lời của bạn._ đã bẻ khóa tôi! – Prince

1

Biết rằng bạn đang xử lý mảng byte UTF-8, bạn chắc chắn sẽ muốn sử dụng String constructor that accepts a charset name. Nếu không, bạn có thể để bản thân mở một số lỗ hổng bảo mật dựa trên mã hóa ký tự. Lưu ý rằng nó ném UnsupportedEncodingException mà bạn sẽ phải xử lý.Một cái gì đó như thế này:

public String openFileToString(String fileName) { 
    String file_string; 
    try { 
     file_string = new String(_bytes, "UTF-8"); 
    } catch (UnsupportedEncodingException e) { 
     // this should never happen because "UTF-8" is hard-coded. 
     throw new IllegalStateException(e); 
    } 
    return file_string; 
} 
2

Bạn có thể sử dụng phương pháp mô tả trong câu hỏi này (đặc biệt là kể từ khi bạn bắt đầu với một InputStream): Read/convert an InputStream to a String

Đặc biệt, nếu bạn không muốn phải dựa vào thư viện bên ngoài , bạn có thể thử this answer, đọc số InputStream qua một số InputStreamReader vào bộ đệm char[] và thêm vào một số StringBuilder.

+0

+1 để đề cập đến các giải pháp thay thế. – CoolBeans

0

Tại sao không nhận được những gì bạn đang tìm kiếm từ khi bắt đầu và đọc một chuỗi từ tệp thay vì một mảng byte? Một cái gì đó như:

BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("foo.txt"), Charset.forName("UTF-8")); 

sau đó đọcLưu ý từ cho đến khi hoàn tất.

+0

Đôi khi, rất hữu ích để giữ các dấu phân tách dòng gốc. OP có thể muốn điều đó. – Bruno

2

Đây là một hàm được đơn giản hóa sẽ đọc theo byte và tạo chuỗi. Nó giả định bạn có thể đã biết những gì mã hóa các tập tin trong (và nếu không mặc định).

static final int BUFF_SIZE = 2048; 
static final String DEFAULT_ENCODING = "utf-8"; 

public static String readFileToString(String filePath, String encoding) throws IOException { 

    if (encoding == null || encoding.length() == 0) 
     encoding = DEFAULT_ENCODING; 

    StringBuffer content = new StringBuffer(); 

    FileInputStream fis = new FileInputStream(new File(filePath)); 
    byte[] buffer = new byte[BUFF_SIZE]; 

    int bytesRead = 0; 
    while ((bytesRead = fis.read(buffer)) != -1) 
     content.append(new String(buffer, 0, bytesRead, encoding)); 

    fis.close();   
    return content.toString(); 
} 
+0

Mã được chỉnh sửa để đặt mặc định là utf-8 để khớp với câu hỏi của OP. – scottt

0

tôi sử dụng cách này

String strIn = new String(_bytes, 0, numBytes);

+1

Điều này không chỉ định bộ ký tự để bạn có được bộ ký tự mặc định nền tảng mà có thể không phải là UTF-8. –

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