简体   繁体   English

如何替换被同一进程锁定的文件?

[英]How can I replace a file which is locked by the same process?

I'm trying to resize an image. 我正在尝试调整图像大小。 Firstly I read the image into a byte array, resize it in memory and write it back to the same file: 首先,我将图像读入字节数组,在内存中调整大小并将其写回到同一文件:

    public static void CropAndResizeImage(EntryImage image, int left, int top, int right, int bottom)
    {
        Size newSize = new Size();
        string imagePathAndFilename = HttpContext.Current.Server.MapPath(image.URL);

        //byte[] photoBytes = File.ReadAllBytes(imagePathAndFilename);
        using (FileStream fs = new FileStream(imagePathAndFilename, FileMode.Open, FileAccess.ReadWrite))
        {
            fs.Position = 0;
            var photoBytes = new byte[fs.Length];
            int read = fs.Read(photoBytes, 0, photoBytes.Length);

            // Process photo and resize
            using (MemoryStream inStream = new MemoryStream(photoBytes))
            using (MemoryStream outStream = new MemoryStream())
            {
                using (ImageFactory imageFactory = new ImageFactory(preserveExifData: true))// Initialize the ImageFactory using the overload to preserve EXIF metadata.
                {

                    ISupportedImageFormat format = new JpegFormat { Quality = 75 }; // Format is automatically detected though can be changed.
                    Size maxSize = new Size(1024, 1024);
                    ResizeLayer layer = new ResizeLayer(maxSize, upscale: false, resizeMode: ResizeMode.Max);
                    layer.Upscale = false;

                    // Load, resize, set the format and quality and save an image.
                    imageFactory.Load(inStream)
                                .Crop(new CropLayer(left, top, right - left, bottom - top, CropMode.Pixels)) // Crop is relative to image edge, not absolute coords.
                                .Resize(layer)
                                .Format(format)
                                .Save(outStream);

                    newSize.Width = imageFactory.Image.Width;
                    newSize.Height = imageFactory.Image.Height;
                }

                // Write back to the same file
                fs.Position = 0;
                fs.SetLength(photoBytes.Length);
                fs.Write(photoBytes, 0, photoBytes.Length);
            }
        }
    }

However usually get the following error: 但是通常会出现以下错误:

The process cannot access the file: 'C:\\folder\\image.jpg' because it is being used by another process. 该进程无法访问文件:'C:\\ folder \\ image.jpg',因为它正在被另一个进程使用。

Why is this? 为什么是这样? I would have presumed that File.ReadAllBytes() would close the file automatically? 我以为File.ReadAllBytes()会自动关闭文件?

No file handles or locks are shown for the file in Process Explorer (which seems odd). 在Process Explorer中没有显示文件的文件句柄或锁(这很奇怪)。

Even if I add some delays in a while loop, the loop never completes, implying the file is permanently locked: 即使我在while循环中添加了一些延迟,循环也永远不会完成,这意味着文件已被永久锁定:

bool saved = false;
while (!saved)
{
    try
    {
        SaveImageToFile(imagePathAndFilename, outStream);
        saved = true;
    }
    catch (IOException ex)
    {
        System.Threading.Thread.Sleep(1000);
    }
}

EDIT: Updated to show the full code and incorporated Mechanic's answer into my code above to show my implementation. 编辑:更新以显示完整的代码,并在上面的代码中结合了Mechanic的答案以显示我的实现。

Instead of Reading all Bytes could you use a FileStream and maintain a hold on the file? 您可以使用FileStream并保持对文件的保留,而不是读取所有字节? Sorry if this code isn't exact, and you may need to trim the access bytes if your file length shortens using the fs.SetLength function 抱歉,如果此代码不正确,并且使用fs.SetLength函数缩短文件长度,则可能需要修整访问字节。

using (FileStream fs = new FileStream(imagePathAndFilename, FileMode.Open, FileAccess.ReadWrite))   
{
    fs.Position = 0;
    var buffer = new byte[fs.Length];
    int read = fs.Read(buffer, 0, buffer.Length);

    // Manipulate bytes here

    fs.Position = 0;
    fs.SetLength(buffer.Length);
    fs.Write(buffer, 0, buffer.Length);
}

EDIT: Added the SetLength to change the stream size 编辑:添加了SetLength来更改流大小

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM