2011-11-26 44 views
9

Tôi chỉ mới bắt đầu tìm hiểu về việc nén tệp và tôi đã gặp phải một chút rào cản. Tôi có một ứng dụng sẽ mã hóa một chuỗi như "chương trình" như là một đại diện nhị phân nén "010100111111011000" (lưu ý điều này vẫn được lưu trữ như một String).Chuyển đổi biểu diễn chuỗi các bit thành một byte

Encoding 
g  111 
r  10 
a  110 
p  010 
o  011 
m  00 

Bây giờ tôi cần phải viết này để các hệ thống tập tin bằng cách sử dụng FileOutputStream, vấn đề tôi đang gặp là, làm thế nào tôi có thể chuyển đổi chuỗi "010100111111011000" tới byte[]/byte s được ghi vào tệp hệ thống với FileOutputStream?

Tôi chưa từng làm việc với bit/byte trước đây nên tôi sắp chết ở đây.

+0

Bạn nói về "biểu diễn nhị phân đã nén", sau đó nói rằng bạn có 'Chuỗi' dài 18 ký tự (" 010100111111011000 ") đại diện cho một từ dài 7 ký tự (" chương trình "). Bạn có chắc chắn là bạn muốn nói gì không? Thông thường bạn sẽ có những bit được thiết lập trong X số byte (3 trong trường hợp này). –

+0

Tra cứu 'toán tử thay đổi bit': '>>', '>>>', '<<'. – Kevin

+0

Brian, thư gốc có kích thước 56bits khi dịch sang nhị phân, thông điệp được mã hóa chỉ là 18bits. Kevin, mọi người cứ nói với tôi điều đó, nhưng tôi vẫn không thể vẽ liên kết giữa việc sử dụng những toán tử đó và có thể dịch nó thành mảng byte. –

Trả lời

6

Giới thiệu về khai thác chút ca:

Thứ nhất, chúng tôi có các nhà điều hành trái ca, x << n. Điều này sẽ thay đổi tất cả các bit trong x trái bởi n bit, điền các bit mới với zero:

 1111 1111 
<< 3: 1111 1000 

Tiếp theo, chúng tôi đã ký kết các nhà điều hành phải thay đổi, x >> n. Sự dịch chuyển về tất cả các bit trong x đúng bởi n, sao chép các bit dấu vào các bit mới:

 1111 1111 
>> 3: 1111 1111 

     1000 0000 
>> 3: 1111 0000 

     0111 1111 
>> 3: 0000 1111 

Cuối cùng, chúng tôi có các nhà điều hành zero-điền đúng ca, x >>> n. Sự dịch chuyển về tất cả các bit trong x đúng bởi n bit, điền các bit mới với zero:

 1111 1111 
>>> 3: 0001 1111 

Bạn cũng có thể thấy hữu ích Bitwise-hoặc nhà điều hành, x | y.Này so sánh các bit trong mỗi vị trí trong xy, thiết lập bit số điện thoại mới về nếu nó đã được trên một trong hai x hoặc y, ngoài khơi cách khác:

1010 0101 
| 1010 1010 
    --------- 
    1010 1111 

Bạn chỉ nên cần các nhà khai thác trước cho vấn đề trong tầm tay , nhưng vì lợi ích của sự hoàn chỉnh, đây là cuối cùng hai:

các Bitwise-và điều hành, x & y đặt các bit ở đầu ra để một khi và chỉ khi các bit đang bật trong cả xy:

1010 0101 
& 1010 1010 
    --------- 
    1010 0000 

Nhà điều hành Bitwise-xor, x^y đặt các bit đầu ra để một nếu các bit đang bật trong một số hay cách khác nhưng không được cả hai:

1010 0101 
^ 1010 1010 
    --------- 
    0000 1111 

Bây giờ, áp dụng các tình huống ở bàn tay:

Bạn sẽ cần sử dụng toán tử dịch bit để thêm và thao tác bit. Bắt đầu thiết lập các bit ở phía bên phải theo biểu diễn chuỗi của chúng và dịch chuyển chúng. Tiếp tục cho đến khi bạn nhấn vào cuối của một byte, và sau đó di chuyển đến byte tiếp theo. Giả sử chúng tôi muốn tạo biểu diễn byte là "1100 1010":

Our byte Target 
--------- -------- 
0000 0000 
      1100 1010 
0000 0001 ^
      1100 1010 
0000 0011 ^
      1100 1010 
0000 0110 ^
      1100 1010 
0000 1100 ^
      1100 1010 
0001 1001  ^
      1100 1010 
0011 0010  ^
      1100 1010 
0110 0101  ^
      1100 1010 
1100 1010   ^

Tôi sẽ, tất nhiên, hãy để bạn áp dụng điều này cho công việc của bạn.

+0

Một câu hỏi, để bắt đầu byte của tôi là 0000 0001, điều này giống như viết byte b = 1; ? Tôi không chắc chắn, vì bản chất đã ký của byte, làm thế nào để biết biểu diễn nhị phân là gì bởi vì tôi không biết bit nào đại diện cho dấu. –

+0

Bạn có thể làm điều đó, nhưng để nhất quán, bạn sẽ muốn bắt đầu với một byte không và sau đó nhập một vòng lặp 'for' hoặc' while'. Tôi sẽ chỉnh sửa ví dụ một chút để xem liệu tôi có thể làm cho điều này rõ ràng hơn một chút hay không. – Kevin

0

Tôi đoán, bạn muốn viết các số 0 và số này dưới dạng giá trị nhị phân trong một tệp. Vì vậy, bạn có thể lặp lại chuỗi lấy 8 dấu hiệu mỗi lần (String.substring() hoặc smth) và tạo các byte với hàm tạo Byte (String). Đó là giải pháp đơn giản nhất hiện ra trong đầu tôi.

Nếu tôi không đúng về vấn đề này, hãy nói thêm về vấn đề này.

+0

Tôi đã thử điều này, Byte (String) constructor sẽ lấy một chuỗi "0011" và nghĩa đen giải thích nó như số thập phân 11. –

+0

Đó là lý do tại sao bạn nên Byte (String s, int radix) constructor để thiết lập cơ số nhị phân. –

1

Cắt String của bạn lên độ dài 8 và gọi Byte#parseByte. Nếu bạn đặt radix thành 2, nó sẽ phân tích cú pháp số String dưới dạng số nhị phân.

+1

Ngoại lệ trong chuỗi "main" java.lang.NumberFormatException: Giá trị nằm ngoài phạm vi. Giá trị: "10000000" Radix: 2 Nó chỉ hoạt động trên độ dài 7 trừ khi có số 0 đứng đầu, bất kỳ ý tưởng nào? –

+0

@ John Lotacs Tôi không biết tại sao nó làm điều này, nhưng bạn có thể sử dụng ['Integer # parseInt'] (http://tinyurl.com/7uo6b5t) và đưa nó vào' byte' để giải quyết. – Jeffrey

+0

@jeff Nó làm điều đó bởi vì 'byte' được ký, vì vậy nó cần phải là' -111 1111' đến '+111 1111' (-128 đến +127). Một byte với các bit của '1000 0000' thực sự là -128, và sẽ phải được cung cấp cho trình phân tích cú pháp là' -1000 0000'. – Kevin

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