Как я могу загрузить изображение из файла, не сохраняя файл заблокированным?

#.net #winforms #graphics

#.net #winforms #графика

Вопрос:

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

pictureBox.Image = Image.FromFile( fileName );

Однако при этом файл остается заблокированным. Затем я попытался прочитать поток:

 using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
    pictureBox.Image = Image.FromStream(fs);
} 
  

Это не блокирует файл, но вызывает исключение, которое будет сгенерировано позже; MSDN указывает, что поток должен оставаться открытым в течение всего срока службы изображения. (Исключение включает сообщение о том, что «Закрытый файл, возможно, не прочитан» или подобное.)

Как я могу загрузить изображение из файла, а затем не иметь дальнейших ссылок на файл?

Ответ №1:

Извините, что отвечаю на свой собственный вопрос, но я подумал, что это слишком полезно, чтобы держать при себе.

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

 using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    fs.CopyTo(ms);
    ms.Seek(0, System.IO.SeekOrigin.Begin);
    pictureBox.Image = Image.FromStream(ms);
} 
  

Ответ №2:

Для тех, кто работает ниже Framework 4.0, вот что я сделал:

 Using fs As New System.IO.FileStream(cImage, IO.FileMode.Open, IO.FileAccess.Read)
            Dim buffer(fs.Length) As Byte
            fs.Read(buffer, 0, fs.Length - 1)
            Using ms As New System.IO.MemoryStream
                ms.Write(buffer, 0, buffer.Length - 1)
                picID.Image = Image.FromStream(ms)
            End Using
        End Using