代码之家  ›  专栏  ›  技术社区  ›  zxcvbnm

C:为什么我得到“进程无法访问文件*,因为它正被另一个进程使用”这个代码?

  •  4
  • zxcvbnm  · 技术社区  · 16 年前

    我正在尝试将文件夹中的bmp文件转换为jpg,然后删除旧文件。代码运行良好,但无法删除BMP。

    DirectoryInfo di = new DirectoryInfo(args[0]);
    FileInfo[] files = di.GetFiles("*.bmp");
    foreach (FileInfo file in files)
    {
        string newFile = file.FullName.Replace("bmp", "jpg");
        Bitmap bm = (Bitmap)Image.FromFile(file.FullName);
        bm.Save(newFile, ImageFormat.Jpeg);
    }
    for (int i = 0; i < files.Length; i++)
        files[i].Delete();
    

    其他程序/进程没有使用这些文件,如错误所示,因此我假设问题就在这里。但对我来说,代码似乎很好,因为我按顺序做每件事。这也是程序的全部功能,所以错误不能由其他地方的代码引起。

    6 回复  |  直到 16 年前
        1
  •  5
  •   Andrew Bezzub    16 年前

    尝试使用包装位图 using :

    using (Bitmap bm = (Bitmap)Image.FromFile(file.FullName))
    {
        bm.Save(newFile, ImageFormat.Jpeg);
    }
    

    这将在保存位图对象后立即处理它们。

        2
  •  1
  •   takrl cck    15 年前
    public static Image LoadImage( string fileFullName )
    {
        Stream fileStream = File.OpenRead( fileFullName );
        Image image       = Image.FromStream( fileStream );
    
        // PropertyItems seem to get lost when fileStream is closed to quickly (?); perhaps
        // this is the reason Microsoft didn't want to close it in the first place.
        PropertyItem[] items = image.PropertyItems;
    
        fileStream.Close();
    
        foreach ( PropertyItem item in items )
        {
            image.SetPropertyItem( item );
        }
    
        return image;
    }
    
        3
  •  0
  •   Matt Brunell    16 年前

    位图对象封装一个文件句柄。调用save之后,必须对位图对象调用dispose。

    你看到了一个问题,因为那些位图对象还没有被垃圾收集。

        4
  •  0
  •   Aaron    16 年前

    保存bm.save之后,应该释放位图对象。尝试添加 bm.Dispose(); 之后 bm.Save(newFile, ImageFormat.Jpeg)

        5
  •  0
  •   Sameh Deabes    16 年前

    MSDN :

    在释放之前请始终调用dispose 你最后一次提到这张照片。 否则,它使用的资源 直到垃圾被释放 收集器调用图像对象的 最后确定方法。

    我不确定在那之后您将如何处理这些图像,但有时您还需要将图像引用设置为空,然后调用gc.collect()。

        6
  •  0
  •   Ian Mercer    16 年前

    解决image.fromfile的问题的最好方法是使用image.fromstream来代替。

    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
       using (Image original = Image.FromStream(fs))
       {
         ...
    

    使用显式dispose()、using()语句或将值设置为null并不能解决问题,除非发生垃圾收集(强制进行垃圾收集通常是一个坏主意)。