[英]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.