Сохраняет ли .NET Streams память? - PullRequest
5 голосов
/ 26 февраля 2009

Пример:

  1. Если я читаю файл и копирую его в другой файл через .NET Streams, будет ли общий размер файла занимать память в любой момент? Или байты будут сброшены, как только они будут использованы?
  2. Если наивный подход не экономит память, будут ли буферизованные потоки делать это?

Ответы [ 4 ]

13 голосов
/ 26 февраля 2009

Если вы выполняете потоковое копирование, то есть читаете буфер, пишете буфер, читаете буфер, пишете буфер и т. Д., Пока у вас не закончатся данные, это займет столько же памяти, сколько размер буфера. Я ожидаю, что File.Copy сделает это (в родном коде Windows, по общему признанию).

Если вы хотите сделать это самостоятельно, используйте что-то вроде этого:

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);
    }
}

Это займет всего 32 КБ, как бы ни был велик поток.

РЕДАКТИРОВАТЬ: Как отмечалось в комментариях, потоки также могут иметь свои собственные буферы, но дело в том, что вы все равно можете передавать очень большой файл без нехватки памяти.

3 голосов
/ 26 февраля 2009

Если вы называете что-то вроде ReadToEnd(), тогда да, содержимое файла будет загружено в память. Вы правы, предполагая, что использование буфера является подходящим подходом, чтобы гарантировать, что только подмножество данных файла загружается в память в любой момент времени.

2 голосов
/ 26 февраля 2009

Нет, весь файл не будет загружен в память.

Объем памяти будет зависеть от размера буферов, которые вы используете для чтения и записи, и любых внутренних буферов, поддерживаемых потоком.

Класс FileStream использует внутренний буфер, размер которого можно указать при перегрузке конструктора и который по умолчанию равен 0x1000 байт (возможно, зависит от реализации - это значение было получено путем изучения класса FileStream с использованием Lutz Reflector).

1 голос
/ 26 февраля 2009

Это действительно зависит от вашей методологии. Если вы используете поток в качестве временной конечной точки с ReadToEnd(), вы можете загрузить весь файл в память. Если вместо этого вы буферизуете, вы не будете использовать больше, чем бит, по сравнению с размером буфера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...