簡體   English   中英

如何替換被同一進程鎖定的文件?

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

我正在嘗試調整圖像大小。 首先,我將圖像讀入字節數組,在內存中調整大小並將其寫回到同一文件:

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

但是通常會出現以下錯誤:

該進程無法訪問文件:'C:\\ folder \\ image.jpg',因為它正在被另一個進程使用。

為什么是這樣? 我以為File.ReadAllBytes()會自動關閉文件?

在Process Explorer中沒有顯示文件的文件句柄或鎖(這很奇怪)。

即使我在while循環中添加了一些延遲,循環也永遠不會完成,這意味着文件已被永久鎖定:

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

編輯:更新以顯示完整的代碼,並在上面的代碼中結合了Mechanic的答案以顯示我的實現。

您可以使用FileStream並保持對文件的保留,而不是讀取所有字節? 抱歉,如果此代碼不正確,並且使用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);
}

編輯:添加了SetLength來更改流大小

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM