2009-03-30 39 views
22

Tôi phải chuyển đổi một char thành một mảng byte hoặc byte. Trong các ngôn ngữ khác tôi biết rằng một char chỉ là một byte đơn. Tuy nhiên, nhìn vào lớp Java Character, giá trị min của nó là \ u0000 và giá trị tối đa của nó là \ uFFFF. Điều này làm cho nó có vẻ như một char là 2 byte dài.Biểu diễn char dưới dạng byte trong Java

Tôi có thể lưu trữ dưới dạng byte hoặc tôi có cần lưu trữ dưới dạng hai byte không?

Trước khi có ai hỏi, tôi sẽ nói rằng tôi đang cố gắng làm điều này bởi vì tôi đang làm việc dưới một giao diện dự kiến ​​kết quả của tôi là một mảng byte. Vì vậy, tôi phải chuyển đổi char của tôi thành một.

Vui lòng cho tôi biết và giúp tôi hiểu điều này.

Cảm ơn, jbu

Trả lời

34

Để chuyển đổi ký tự để byte, bạn cần phải xác định một character encoding. Một số mã hóa ký tự sử dụng một byte cho mỗi ký tự, trong khi một số khác sử dụng hai hoặc nhiều byte. Thực tế, đối với nhiều ngôn ngữ, có quá nhiều ký tự để mã hóa với một byte đơn.

Trong Java, cách đơn giản nhất để chuyển đổi từ ký tự thành byte là phương thức getBytes(String encoding) của lớp học String. Tuy nhiên, phương thức này sẽ tự động thay thế các ký tự bằng & # xfffd; nếu ký tự không thể được ánh xạ theo mã hóa được chỉ định. Nếu bạn cần kiểm soát nhiều hơn, bạn có thể cấu hình CharsetEncoder để xử lý trường hợp này với lỗi hoặc sử dụng ký tự thay thế khác.

+1

sẽ sử dụng UTF-8 và lưu trữ ký tự của tôi dưới dạng một byte đơn là ok? Tôi nghĩ có, ngay cả khi bit cuối cùng đó là một bit dấu hiệu cho một byte. – jbu

+0

Bạn nên sử dụng mã hóa ký tự được yêu cầu bởi giao diện mà bạn đang làm việc. – erickson

+1

Đối với mã hóa byte đơn sử dụng ISO-8859 gia đình –

0

char trong java là một giá trị 16 bit chưa ký. Nếu những gì bạn có sẽ phù hợp trong 7 bit sau đó chỉ cần làm các diễn viên để một byte (ví dụ ASCII sẽ phù hợp).

Bạn cũng có thể thanh toán các API java.nio.charset.

+0

Nó phải phù hợp với 7 bit để hoạt động an toàn. – erickson

+0

vâng, tôi không muốn tham gia ASCII mở rộng ... nhưng tôi sẽ cập nhật câu trả lời của mình. – TofuBeer

4

Để mở rộng những gì người khác đang nói, nếu bạn có một char mà bạn cần như một mảng byte, thì trước tiên bạn tạo một String chứa rằng char và sau đó nhận được các mảng byte từ String:

private byte[] charToBytes(final char x) { 
    String temp = new String(new char[] {x}); 
    try { 
    return temp.getBytes("ISO-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
    // Log a complaint 
    return null; 
    } 
} 

Tất nhiên, sử dụng bộ ký tự thích hợp. Hiệu quả hơn nhiều là điều này sẽ bắt đầu làm việc với Strings thay vì lấy một char tại một thời điểm, chuyển đổi thành một String, sau đó chuyển đổi thành một mảng byte.

8

Một char thực sự là 16 bit trong Java (và cũng là loại không dấu duy nhất !!).

Nếu bạn chắc chắn mã hóa các ký tự của bạn là ASCII, thì bạn có thể bỏ chúng đi một byte (vì ASCII chỉ sử dụng 7 bit thấp hơn của char).

Nếu bạn không cần phải sửa đổi các ký tự, hoặc hiểu ý nghĩa của họ trong một String, bạn chỉ có thể lưu trữ ký tự trên hai byte, như:

char[] c = ...; 
byte[] b = new byte[c.length*2]; 
for(int i=0; i<c.length; i++) { 
    b[2*i] = (byte) (c[i]&0xFF00)>>8; 
    b[2*i+1] = (byte) (c[i]&0x00FF); 
} 

(Nó có thể được khuyến khích để thay thế 2 * bởi một sự thay đổi đúng, nếu vấn đề tốc độ).

Lưu ý rằng một số ký tự thực (được hiển thị) (hoặc, chính xác hơn, các điểm mã Unicode) được viết trên hai ký tự liên tiếp. Vì vậy, cắt giữa hai ký tự không đảm bảo rằng bạn đang cắt giữa các ký tự thực tế.

Nếu bạn cần giải mã/mã hóa hoặc điều khiển mảng char của bạn theo cách thức nhận dạng String, bạn nên cố giải mã và mã hóa mảng char hoặc chuỗi bằng cách sử dụng java.công cụ io, đảm bảo thao tác nhân vật phù hợp.

+0

Thay vì mã được hiển thị ở đây, hãy chỉ định "UTF-16" làm mã hóa ký tự và sử dụng các API mã hóa tích hợp. Ít mã hơn để bạn triển khai, kiểm tra và bảo trì, đồng thời nắm bắt ý định rõ ràng hơn cho người đọc mã. – erickson

+0

Và cũng có hai đơn đặt hàng có cường độ ít hơn về tốc độ, do mã hóa/giải mã, điều này có thể không cần thiết trong trường hợp này. – Varkhan

+0

Nó chỉ mã hóa và nếu nó chậm hơn (mà tôi nghi ngờ), nó không phải là một yếu tố 100. Tại sao bạn nghĩ rằng mã hóa UTF-16 đang làm bất cứ điều gì khác biệt đáng kể so với mã của bạn? – erickson

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