2011-10-16 2 views
6

Nó nói ở đây msdn.microsoft.com/en-us/library/system.io.stream.read.aspx rằng các phương pháp Stream.ReadStream.Write đều tăng vị trí/bù trừ trong luồng một cách tự động tại sao các ví dụ ở đây là http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspxhttp://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx thay đổi bù trừ theo cách thủ công?Đặt độ lệch trong một dòng

Bạn chỉ đặt độ lệch trong vòng lặp nếu bạn biết kích thước của luồng và đặt thành 0 nếu bạn không biết kích thước và sử dụng bộ đệm?

// Now read s into a byte buffer. 
    byte[] bytes = new byte[s.Length]; 
    int numBytesToRead = (int) s.Length; 
    int numBytesRead = 0; 
    while (numBytesToRead > 0) 
    { 
     // Read may return anything from 0 to 10. 
     int n = s.Read(bytes, numBytesRead, 10); 
     // The end of the file is reached. 
     if (n == 0) 
     { 
      break; 
     } 
     numBytesRead += n; 
     numBytesToRead -= n; 
    } 

using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)) 
{ 
    const int size = 4096; 
    byte[] buffer = new byte[size]; 
    using (MemoryStream memory = new MemoryStream()) 
    { 
    int count = 0; 
    do 
    { 
     count = stream.Read(buffer, 0, size); 
     if (count > 0) 
     { 
     memory.Write(buffer, 0, count); 
     } 
    } 
    while (count > 0); 
    return memory.ToArray(); 
    } 
} 
+0

... Cái gì? –

+0

Có sự khác biệt giữa số bù trong nội bộ trong Luồng và độ dài/độ dài bạn cần quan tâm khi bạn đọc/ghi dữ liệu giữa bộ đệm và luồng và có thể là luồng 2.. – nos

+0

@sehe: Đổ lỗi cho hệ điều hành của bạn. –

Trả lời

4

Sửa (cho câu hỏi đã chỉnh sửa):

Trong không ai trong số các đoạn mã bạn dán vào các câu hỏi tôi thấy bất kỳ dòng bù đắp được thiết lập.

Tôi nghĩ bạn đang nhầm lẫn việc tính toán byte để đọc so với byte nhận được. Giao thức này có vẻ buồn cười (tại sao bạn nhận được ít byte hơn yêu cầu?) Nhưng nó có ý nghĩa khi bạn cho rằng bạn có thể đọc từ nguồn định hướng gói độ trễ cao (nghĩ: ổ cắm mạng).

Bạn có thể nhận được 6 ký tự trong một cụm từ (từ gói TCP) và chỉ nhận được 4 ký tự còn lại trong lần đọc kế tiếp (khi gói tiếp theo đã đến).

Sửa Để đối phó với linked example của bạn từ những nhận xét:

using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)) 
    { 
     // ... snip 

     count = stream.Read(buffer, 0, size); 
     if (count > 0) 
     { 
     memory.Write(buffer, 0, count); 
     } 

Dường như các lập trình viên sử dụng kiến ​​thức trước về việc thực hiện dòng cơ bản, đó stream.Read sẽ luôn luôn trở về 0 HOẶC kích thước yêu cầu. Điều đó có vẻ giống như một vụ cá cược nguy hiểm đối với tôi. Nhưng nếu các tài liệu cho GZipStream làm điều đó, nó có thể được alright. Tuy nhiên, vì các mẫu MSDN sử dụng biến số Stream chung, đó là (cách) chính xác hơn để kiểm tra số byte chính xác đã đọc.


Ví dụ được liên kết đầu tiên sử dụng MemoryStream trong cả thời trang Viết và Đọc. Vị trí được thiết lập lại ở giữa, do đó dữ liệu được viết đầu tiên sẽ được đọc:

Stream s = new MemoryStream(); 
    for (int i = 0; i < 100; i++) 
    { 
     s.WriteByte((byte)i); 
    } 
    s.Position = 0; 

Ví dụ thứ hai liên kết không không thiết lập vị trí dòng. Bạn thường đã thấy một cuộc gọi đến Seek nếu có. Bạn có thể nhầm lẫn các offset vào bộ đệm dữ liệu với vị trí dòng?

+1

Tôi không nói về phần viết, ý tôi là phần đọc. Tôi đã so sánh ví dụ MS với http://www.dotnetperls.com/decompress – Jonas

+1

@Jonas: và tôi cũng đã giải quyết mẫu GZipStream, bây giờ là – sehe

+0

Ồ, tôi thấy, 's.Read (bytes, numBytesRead, 10);' là thực sự bù đắp cho bộ đệm byte? Vì vậy, 'numBytesRead' là thiết lập vị trí trong bộ đệm, chứ không phải luồng. – Jonas

9

Độ lệch thực tế là độ lệch của bộ đệm chứ không phải luồng. Các luồng được tự động nâng cao khi chúng được đọc.