当前位置: 首页 > 知识库问答 >
问题:

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

赏开宇
2023-03-14

我正在尝试调整图像的大小。首先,我将图像读入字节数组,在内存中调整大小并将其写回同一个文件:

    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()会自动关闭文件?

进程资源管理器中没有显示文件句柄或锁(这似乎很奇怪)。

即使我在while循环中添加了一些延迟,循环也永远不会完成,这意味着文件被永久锁定:

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

编辑:更新以显示完整的代码,并将机械师的答案合并到我上面的代码中以显示我的实现。

共有1个答案

钱凌
2023-03-14

您可以使用文件流并保留文件,而不是读取所有字节吗?如果此代码不准确,很抱歉,如果文件长度使用fs缩短,您可能需要修剪访问字节。设置长度函数

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以更改流大小

 类似资料:
  • 存储区及其锁文件已被另一个进程锁定:/home/dev/neo4j-community-2.3.2/data/graph.db/store_lock。请确保没有其他进程正在使用此数据库,并且目录是可写的(即使是只读访问也是必需的) 我知道这是因为neo4j服务器应用程序正在运行,它将目录锁定为另一个应用程序的可写目录。 但是我想同时运行这两个功能,neo4j服务器与browser studio和我

  • 我需要创建一个锁文件,不能被其他脚本或进程删除。我试过这个: 但是,从当前用户启动的任何其他进程都可以删除文件,即使文件句柄仍然由正在运行的脚本打开。如何解决此问题并防止其他人(即非PHP进程)删除该文件?进程退出时自动释放的锁?所有类似的问题都以RTM flock()结尾,但没有一个回答如何针对外部进程锁定文件。 OS是

  • 本文向大家介绍oracle查看被锁的表和被锁的进程以及杀掉这个进程,包括了oracle查看被锁的表和被锁的进程以及杀掉这个进程的使用技巧和注意事项,需要的朋友参考一下 -- 1. 查看被锁的表 -- 2. 查看是哪个进程锁的 -- 3. 杀掉这个进程

  • 问题内容: 这是场景:我有一个在servlet容器中运行的多线程Java Web应用程序。该应用程序在servlet容器内多次部署。在不同的服务器上运行着多个servlet容器。 也许这张图很清楚: 网络共享目录中有一个文件,所有这些线程都可以访问。而且他们确实经常访问该文件。在大多数情况下,文件仅由那些线程读取。但有时它是书面的。 我需要一个故障保护解决方案来同步所有这些线程,以便保证数据的一致

  • 问题内容: UNIX文件锁定非常简单:操作系统假定您知道自己在做什么,然后就可以按照自己的意愿进行操作: 例如,如果您尝试删除另一个进程已打开的文件,则操作系统通常会允许您执行此操作。原始进程仍将保留其文件句柄,直到它终止-这时文件系统将安静地回收磁盘资源。不用大惊小怪,这就是我喜欢的方式。 Windows上的不同之处:如果我尝试删除另一个进程正在使用的文件,则会出现操作系统错误。在原始进程释放它

  • 问题内容: 如何使用php替换特定行。我不知道行号。我要替换包含特定单词的行。 问题答案: 您可以在较小的文件上使用一种方法,该文件可以两次装入您的内存: 快速说明,PHP> 5.3.0支持lambda函数,因此您可以删除命名的函数声明并将映射缩短为: 从理论上讲,您可以使它成为单个(很难理解)的php语句: 您应该对较大的文件使用另一种(较少占用内存的方法):