2012-03-07 41 views
21

Tôi đang đọc một tệp thành một mảng byte theo khối và gửi nó qua mạng qua yêu cầu POST tới máy chủ web. Nó không phải là bất cứ điều gì phức tạp, tôi đã thực hiện nó trước khi sử dụng mã chính xác này. Lần này, tôi nhận thấy rằng hình ảnh của tôi trông thật kỳ quặc khi họ đến máy chủ, vì vậy tôi quyết định xem mảng byte đang được gửi và mảng được nhận chỉ để đảm bảo nó giống nhau. Nó không phải. Về phía gửi java, mảng byte chứa số âm. Trên mặt nhận C#, không có số âm.Mảng byte Java chứa số âm

15 byte đầu tiên ở phía bên nhận (C#)

137 
80 
78 
71 
13 
10 
26 
10 
0 
0 
0 
13 
73 
72 
68 

Những byte tương tự nhưng ở phía bên gửi (java)

-119 
80 
78 
71 
13 
10 
26 
10 
0 
0 
0 
13 
73 
72 
68 

Tất cả các số không âm đều giống nhau và -119 không phải là số âm duy nhất, tất cả đều kết thúc. Tôi đã nhận thấy rằng -119 và 137 là 256 ngoài và tự hỏi nếu điều đó có cái gì để làm với nó.

Mã Tôi đang sử dụng để đọc các hình ảnh (java)

public static byte[] readPart(String fileName, long offset, int length) throws FileNotFoundException, Exception 
{ 
    byte[] data = new byte[length]; 
    File file = new File(fileName); 
    InputStream is = new FileInputStream(file); 
    is.skip(offset); 
    is.read(data,0,data.length); 
    is.close(); 
    return data; 
} 

Mã Tôi đang sử dụng để ghi dữ liệu (C#)

private void writeFile(string fileName, Stream contents) 
    { 
     using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) 
     { 
      int bufferLen = 65000; 
      byte[] buffer = new byte[bufferLen]; 
      int count = 0; 
      while ((count = contents.Read(buffer, 0, bufferLen)) > 0) 
      { 
       fs.Write(buffer, 0, count); 
      } 
      fs.Close(); 
     } 
     contents.Close(); 
    } 

Tôi không biết nếu đó là điều gì đó luôn luôn xảy ra và tôi chưa bao giờ để ý đến nó trước đây hoặc nếu đó là điều gì đó quyết định sai lầm khủng khiếp. Những gì tôi biết là mã này đã làm việc trước đây cho một cái gì đó rất giống nhau và nó không hoạt động ngay bây giờ.

Nếu có ai có bất kỳ đề xuất hoặc giải thích nào, tôi thực sự sẽ đánh giá cao nó.

CHỈNH SỬA: Lý do hình ảnh của tôi trông kỳ lạ là cách tôi gọi phương thức readPart.

byte[] data = FileUtilities.readPart(fileName,counter,maxFileSize);//counter is the current chunk number 

Làm thế nào tôi nên đã gọi đó là

byte[] data = FileUtilities.readPart(fileName,counter*maxFileSize,maxFileSize);//the current chunk * cuhnksize for the offset... 

Cảm ơn tất cả mọi người, tôi là đáng kể ít bối rối bây giờ :)

+0

Chỉ cố gắng tạo tất cả các byte tích cực trước khi chúng được gửi bằng dữ liệu [i] = (byte) Math.abs ((int) dữ liệu [i]); Điều đó không hiệu quả, nó cho tôi biết hình ảnh bị hỏng tại điểm đó. – nick

+0

Chỉ là byte đầu tiên của toàn bộ tệp, hoặc byte đầu tiên của mỗi đoạn? –

+2

'byte' của Java được ký, vì vậy không thể có 137 được lưu trữ trong một' byte'. Có lẽ vấn đề của bạn đến từ điều này? – Laf

Trả lời

25

Java không có byte unsigned; tất cả các byte được coi là đã ký. Đó là tất cả.

Tất cả những điều thực sự quan trọng là cách bạn nghĩ rằng của các byte, vì bạn hiếm khi thực sự cần phải so sánh các byte. Sự khác biệt đáng kể duy nhất là chúng in ra như đã ký, như bạn đã khám phá ra.

Nếu bạn thích, bạn có thể sử dụng ví dụ: Các tiện ích UnsignedBytes của ổi để xem các byte Java là chưa ký, nhưng thực sự không có nhiều khác biệt thực tế.

+3

Và trong C#, 'byte' không được ký và' sbyte' được ký. –

26

Trong Java, byte là giá trị đã ký (sử dụng two's complement để mã hóa giá trị âm), vì vậy bạn thấy chính xác điều đó nếu không mong muốn của hầu hết mọi người.

Để chuyển đổi một byte đến một giá trị unsigned int, sử dụng b & 0xff

+2

Tôi có thể xác nhận nó hoạt động, và loại hiểu nó. Ngoài ra thêm + 256 vào đó -25 (trong trường hợp của tôi 0xE7) thực sự hoạt động như là tốt. Tuy nhiên, tôi không * hoàn toàn * nắm bắt được vấn đề thực sự ở đây là gì. Bạn có thể giải thích thêm một chút về sự dịch chuyển bit không? –

+1

'(byte) 0xE7 + 256' chuyển đổi byte đã ký thành' int' (vẫn cung cấp cho bạn -25) và sau đó thêm '(int) 256'. Để hiểu đầy đủ về những gì đang xảy ra, trước tiên bạn phải hiểu rằng mọi thứ chỉ là một mẫu bit và * bạn * đang cho những bit đó có ý nghĩa bằng cách xác định các phép tính toán theo những cách nhất định để mã hóa những thứ thực. Với kiến ​​thức đó, bạn có thể đọc bài viết được liên kết để hiểu ý nghĩa của mẫu bit. Bước tiếp theo là hiểu các quy tắc mở rộng kiểu Java: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html –

3

Có lẽ nó có cái gì để làm với thực tế là byte Java được ký kết (khoảng -128 đến 127) trong khi C# 's là unsigned (0 đến 255) :). Thông tin này giống nhau ở dạng nhị phân, nó chỉ được diễn giải khác nhau.

9

Giải thích thêm, giả sử bạn có 137 làm byte chưa ký. Điều đó được thể hiện là:

1000 1001 

Giá trị nhị phân này, khi được biểu thị bằng số bổ sung của hai chữ ký, hóa ra là -119. (-128 + 9)

Bất kỳ giá trị byte chưa ký nào trên 128 sẽ bị ảnh hưởng bởi sự khác biệt do bit ngoài cùng bên trái được sử dụng theo cách này bởi lược đồ bổ sung của hai.

+0

Cuối cùng tôi đã có thể xác nhận xem các byte có chính xác không gỡ lỗi. Tôi có -16, mà lần lượt là 240 như ubyte (240 - 256) = - 16 –

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