2009-02-26 7 views
5

Ví dụ:.NET Streams có lưu bộ nhớ không?

  1. Nếu tôi đọc một tập tin và sao chép nó vào tập tin khác thông qua NET Streams tổng kích thước của tập tin sẽ chiếm bộ nhớ bất cứ lúc nào? Hoặc các byte sẽ bị loại bỏ ngay sau khi chúng được sử dụng?
  2. Nếu cách tiếp cận ngây thơ không tiết kiệm bộ nhớ sẽ đệm luồng làm việc đó?
+0

Câu hỏi hay! :) – overslacked

Trả lời

13

Nếu bạn sao chép bản sao, đọc bộ đệm, viết bộ đệm, đọc bộ đệm, ghi bộ đệm vv cho đến khi hết dữ liệu, bộ nhớ sẽ chỉ chiếm nhiều bộ nhớ. Tôi mong đợi File.Copy để làm điều này (trong mã Windows bản địa, phải thừa nhận).

Nếu bạn muốn làm điều đó cho mình, sử dụng một cái gì đó như thế này:

public void CopyData(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[32 * 1024]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

này sẽ chỉ mất 32K tuy nhiên lớn dòng là.

EDIT: Như đã lưu ý trong các nhận xét, các luồng cũng có thể có bộ đệm riêng của chúng, nhưng điểm là bạn vẫn có thể chuyển một tệp rất lớn mà không hết bộ nhớ.

+0

... + kích thước của bất kỳ bộ đệm nội bộ nào được sử dụng bởi Luồng (FileStream sử dụng bộ đệm trong có kích thước mặc định là 4K) – Joe

+0

.NET FileStreams có bộ đệm trong của riêng chúng. Vì vậy, việc sử dụng đoạn mã trên với FileStream có thể mất hơn 32K bộ nhớ (32K + bất kể kích thước bộ đệm trong của FileStream là bao nhiêu). Nhưng trong mọi trường hợp, một lượng bộ nhớ không đổi được sử dụng với kỹ thuật này. –

+0

Điểm tốt, cả hai bạn. Đang cập nhật ... –

3

Nếu bạn gọi một cái gì đó như ReadToEnd() thì có, nội dung của tệp sẽ được tải vào bộ nhớ. Bạn đoán đúng rằng việc sử dụng bộ đệm là cách tiếp cận thích hợp để đảm bảo rằng chỉ một tập hợp con dữ liệu của tệp được tải vào bộ nhớ tại bất kỳ thời điểm nào.

2

Không, toàn bộ tệp sẽ không được tải vào bộ nhớ.

Dấu chân bộ nhớ sẽ tùy thuộc vào kích thước bộ đệm bạn sử dụng để đọc và viết và mọi bộ đệm trong được duy trì bởi luồng.

Lớp FileStream sử dụng bộ đệm bên trong có kích thước có thể được chỉ định trong quá tải khởi tạo và mặc định là 0x1000 byte (có thể là phụ thuộc thực hiện - giá trị này thu được bằng cách kiểm tra lớp FileStream bằng cách sử dụng Lutz Reflector).

1

Nó thực sự phụ thuộc vào phương pháp của bạn. Nếu bạn đang sử dụng luồng làm điểm cuối tạm thời với ReadToEnd(), bạn có thể tải toàn bộ tệp trong bộ nhớ. Nếu thay vào đó, bạn đang đệm, bạn sẽ không sử dụng nhiều hơn một chút chi phí trên kích thước bộ đệm.

+0

Lưu ý ngắn gọn: ReadToEnd() tồn tại trên TextReader, không phải Luồng. –