Загрузка файла к Битовому массиву, но отъезд исходного неповрежденного файла

Как сделать это в C#?

Если я использую Битовый массив. FromFile (), исходный файл заблокирован.

Если я использую Битовый массив. FromStream (), исходный файл не заблокирован, но в документации говорится, что "Необходимо сохранить поток открытым в течение времени жизни Изображения". Это, вероятно, означает, что файл все еще связан с объектом изображения, (например, возможно, если изменение файла также - объект или наоборот).

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

7
задан Louis Rhys 2 August 2010 в 10:11
поделиться

3 ответа

Немного справочной информации о таком поведении: Bitmap использует файл, отображенный в памяти, для доступа к пикселям в растровом изображении. Это очень базовая возможность в Windows API, она позволяет очень эффективно отображать память на данные файла. Данные считываются из файла только тогда, когда программа считывает память, страницы виртуальной памяти не занимают места в файле подкачки Windows.

Точно такой же механизм используется для загрузки сборок .NET. Именно отображение памяти накладывает блокировку на файл. Именно поэтому сборки блокируются, когда они используются в программе .NET. Метод Image.Dispose() снимает блокировку. Борьба с блокировкой часто указывает на то, что вы забываете утилизировать свои растровые изображения. Очень важно, что забывание вызвать Dispose() не часто вызывает проблемы для классов .NET, за исключением Bitmap, поскольку ему может потребоваться очень много (неуправляемой) памяти.

Да, FromStream() не позволяет классу сделать эту оптимизацию. Затраты значительны, вам потребуется вдвое больше памяти при загрузке растрового изображения. Это будет проблемой, когда битмап большой, вы уклоняетесь от OOM, когда программа работает некоторое время (фрагментируя адресное пространство), и она не работает на 64-битной операционной системе. Определенно не делайте этого, если ширина x высота x 4 растровой карты >= 45 МБ, плюс-минус.

Немного кода, вам не нужно прыгать через CopyStream:

    public static Image LoadImageNoLock(string path) {
        var ms = new MemoryStream(File.ReadAllBytes(path)); // Don't use using!!
        return Image.FromStream(ms);
    }

Обратите внимание, что вы не хотите утилизировать MemoryStream, вы получите трудно диагностируемую "общую ошибку" при использовании растрового изображения. Причина - ленивое чтение потока классом Image.

26
ответ дан 6 December 2019 в 05:38
поделиться

Чтобы создать изображение без блокировки файла, вам нужно будет создать копию FileStream изображения. Проверьте эту страницу Лучший способ копирования между двумя экземплярами Stream - C # , чтобы узнать, как копировать поток.

После этого просто создайте свое изображение из скопированного потока, и все готово.

4
ответ дан 6 December 2019 в 05:38
поделиться

Считайте файл в память, скопировав его из FileStream в MemoryStream . (Найдите CopyStream в Stack Overflow, чтобы найти множество примеров того, как это сделать безопасно. Обычно цикл во время чтения, запись каждого фрагмента в поток памяти, пока не останется данных для чтения.) Затем перемотайте назад MemoryStream (установите Position = 0 ), а затем передайте его в Bitmap.FromStream .

4
ответ дан 6 December 2019 в 05:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: