2011-07-08 29 views
31

Làm cách nào để kiểm tra xem chuỗi có định dạng UTF-8 hợp lệ không?Kiểm tra xem một chuỗi có hợp lệ UTF-8 được mã hóa trong Java

+5

bạn có nghĩa là byte [] là hợp lệ mã hóa? – bestsss

+0

Điều đơn giản nhất có thể là giải mã và mã hóa lại. Kiểm tra bạn nhận được cùng một điều. Điều này sẽ đúng trong hầu hết mọi trường hợp. –

+0

@Peter sẽ không luôn hoạt động vì một số ký tự có thể được mã hóa với các chuỗi byte khác nhau. Cả hai chuỗi byte sẽ đúng, và mã hóa các ký tự giống nhau, nhưng các byte khác nhau. – Jesper

Trả lời

31

Chỉ có thể kiểm tra dữ liệu byte. Nếu bạn đã xây dựng một String thì nó đã có trong UTF-16 nội bộ.

Ngoài ra chỉ mảng byte mới có thể được mã hóa UTF-8.

Đây là trường hợp phổ biến của chuyển đổi UTF-8.

String myString = "\u0048\u0065\u006C\u006C\u006F World"; 
System.out.println(myString); 
byte[] myBytes = null; 

try 
{ 
    myBytes = myString.getBytes("UTF-8"); 
} 
catch (UnsupportedEncodingException e) 
{ 
    e.printStackTrace(); 
    System.exit(-1); 
} 

for (int i=0; i < myBytes.length; i++) { 
    System.out.println(myBytes[i]); 
} 

Nếu bạn không biết mã hóa mảng byte, juniversalchardet là thư viện để giúp bạn phát hiện nó.

+4

Cũng giống như làm rõ, một thể hiện của String không có dạng mã hóa UTF-16, nói đúng, vì nó cho phép các chuỗi đơn vị mã không thành lập (dưới dạng các đơn vị mã thay thế bị cô lập). Đó là, tuy nhiên, một chuỗi Unicode 16-bit. –

+4

Nói đúng hơn, một chuỗi Java cũng không phải là một chuỗi Unicode 16 bit thực sự, vì nó có thể chứa [thay thế] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/ openjdk/6-b14/sun/nio/cs/Surrogate.java) cho các ký tự UCS4 (3 và 4 byte). – rustyx

+0

ICU4J là một thư viện Java khác có thể giúp bạn phát hiện mã hóa của một mảng byte: http://site.icu-project.org/ –

1

Bài đăng sau đây được lấy từ hướng dẫn Java chính thức có tại: https://docs.oracle.com/javase/tutorial/i18n/text/string.html.

Chương trình StringConverter bắt đầu bằng cách tạo ra một String chứa ký tự Unicode:

String original = new String("A" + "\u00ea" + "\u00f1" + "\u00fc" + "C"); 

Khi in, String tên ban đầu xuất hiện như:

AêñüC 

Để chuyển đổi các đối tượng String để UTF -8, gọi phương thức getBytes và chỉ định mã định danh mã hóa thích hợp làm tham số. Phương thức getBytes trả về một mảng byte theo định dạng UTF-8. Để tạo một đối tượng String từ một mảng các byte không phải Unicode, hãy gọi hàm tạo String với tham số mã hóa. Các mã mà làm cho những cuộc gọi được bao bọc trong một khối try, trong trường hợp mã hóa quy định là được hỗ trợ:

try { 
    byte[] utf8Bytes = original.getBytes("UTF8"); 
    byte[] defaultBytes = original.getBytes(); 

    String roundTrip = new String(utf8Bytes, "UTF8"); 
    System.out.println("roundTrip = " + roundTrip); 
    System.out.println(); 
    printBytes(utf8Bytes, "utf8Bytes"); 
    System.out.println(); 
    printBytes(defaultBytes, "defaultBytes"); 
} catch (UnsupportedEncodingException e) { 
    e.printStackTrace(); 
} 

Chương trình StringConverter in ra các giá trị trong utf8Bytes và defaultBytes mảng để chứng minh một điểm quan trọng: Độ dài văn bản được chuyển đổi có thể không giống với độ dài của văn bản nguồn. Một số ký tự Unicode dịch thành các byte đơn, các ký tự khác thành các cặp hoặc ba byte. Phương thức printBytes hiển thị các mảng byte bằng cách gọi phương thức byteToHex, được định nghĩa trong tệp nguồn, UnicodeFormatter.java. Đây là phương thức printBytes:

public static void printBytes(byte[] array, String name) { 
    for (int k = 0; k < array.length; k++) { 
     System.out.println(name + "[" + k + "] = " + "0x" + 
      UnicodeFormatter.byteToHex(array[k])); 
    } 
} 

Đầu ra của phương thức printBytes theo sau. Lưu ý rằng chỉ và cuối cùng byte đầu tiên, A và ký tự C, đều giống nhau ở cả hai mảng:

utf8Bytes[0] = 0x41 
utf8Bytes[1] = 0xc3 
utf8Bytes[2] = 0xaa 
utf8Bytes[3] = 0xc3 
utf8Bytes[4] = 0xb1 
utf8Bytes[5] = 0xc3 
utf8Bytes[6] = 0xbc 
utf8Bytes[7] = 0x43 
defaultBytes[0] = 0x41 
defaultBytes[1] = 0xea 
defaultBytes[2] = 0xf1 
defaultBytes[3] = 0xfc 
defaultBytes[4] = 0x43 
Các vấn đề liên quan