在代码中移动文件后文件锁定错误
File lock errors after moving files in code
我使用以下代码将文件移动到文件夹中
File.Move(Source,Dest);
然后我尝试在下一个方法中打开并读取文件,但我一直被进程错误锁定文件。
所以我将文件移动更改为以下代码
public async static Task<bool> MoveFileAsync(string sourceFileName, string destinationFileName)
{
using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))
{
using(FileStream destinationStream = File.Create(destinationFileName))
{
try
{
await sourceStream.CopyToAsync(destinationStream);
File.Delete(sourceFileName);
return true;
}
catch
{
return false;
}
}
}
}
我不断收到文件锁定的错误
关于如何防止这种情况发生的任何想法。
这都是使用 FileSystemWatcher 来监视文件夹...代码如下。我可以确认 none 这些错误发生在我将文件拖放到文件夹中时......即使我拖动多个文件......
使用系统;
使用 System.Collections.Generic;
使用 System.IO;
使用 System.Linq;
使用 System.Text;
使用 System.Threading.Tasks;
namespace DocumentManager.RepositoryService
{
internal class MonitorDropFolder
{
public string RepositoryPath { get; set; }
public FileSystemWatcher Watcher { get; set; }
public MonitorDropFolder ()
{
Watcher = new FileSystemWatcher();
Watcher.Path = @"c:\Repository\DropLocation";
Watcher.NotifyFilter = NotifyFilters.FileName;
Watcher.Filter = "*.docx";
Watcher.Created += new FileSystemEventHandler(OnCreatedHandler);
StartMonitoring();
}
public void StartMonitoring()
{
Watcher.EnableRaisingEvents = true;
}
public void StopMonitoring()
{
Watcher.EnableRaisingEvents = false;
}
private void OnCreatedHandler(object source, FileSystemEventArgs e)
{
if(e.ChangeType == WatcherChangeTypes.Created)
{
//don't process temporary files
if (Path.GetFileName(e.FullPath).Substring(0, 1) == "~" || Path.GetFileName(e.FullPath).Substring(0, 1) == "$")
return;
var result = convert(e.FullPath, GetDocStatus(e.Name)).Result;
FileService.MoveNativeToDraft(e.FullPath);
}
}
private async Task<bool> convert(string fileName, string docStatus)
{
try
{
ConvertWordToPDF convertor = new ConvertWordToPDF();
var task = Task.Run(()=>convertor.Convert(fileName, docStatus));
await task;
return true;
}
catch (Exception)
{
return false;
}
}
}
}
提前致谢
更新:
我这样调用代码...
public static void MoveIntoRepository(string sourceFile)
{
string destinationDir = @"C:\Repository\DropLocation\";
var result = MoveFileAsync(sourceFile, Path.Combine(destinationDir, Path.GetFileName(sourceFile))).Result;
}
我也试过像这样绕过文件锁...
bool isFileLocked = isLocked(filename);
int numTries = 0;
while(isFileLocked)
{
numTries++;
if (numTries > 100)
throw new Exception("FileLock Error");
///the following is actually in a called method
byte[] byteArray = File.ReadAllBytes(filename);
///... rest of code here
Thread.Sleep(500);
isFileLocked = isLocked(filename);
}
调用此方法
private static bool isLocked(string filename)
{
try
{
FileStream st = new FileStream();
st = File.Open(filename,FileMode.Open);
st.Close();
return false;
}
catch (Exception)
{
return true;
throw;
}
}
在代码下面查看我的评论:
using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))
{
using(FileStream destinationStream = File.Create(destinationFileName))
{
try
{
await sourceStream.CopyToAsync(destinationStream);
// The sourceFileName file is locked since you are inside the
// the using statement. Move statement for deleting file to
// outside the using.
File.Delete(sourceFileName);
return true;
}
catch
{
return false;
}
}
}
// Move it here
我使用以下代码将文件移动到文件夹中
File.Move(Source,Dest);
然后我尝试在下一个方法中打开并读取文件,但我一直被进程错误锁定文件。
所以我将文件移动更改为以下代码
public async static Task<bool> MoveFileAsync(string sourceFileName, string destinationFileName)
{
using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))
{
using(FileStream destinationStream = File.Create(destinationFileName))
{
try
{
await sourceStream.CopyToAsync(destinationStream);
File.Delete(sourceFileName);
return true;
}
catch
{
return false;
}
}
}
}
我不断收到文件锁定的错误
关于如何防止这种情况发生的任何想法。
这都是使用 FileSystemWatcher 来监视文件夹...代码如下。我可以确认 none 这些错误发生在我将文件拖放到文件夹中时......即使我拖动多个文件...... 使用系统; 使用 System.Collections.Generic; 使用 System.IO; 使用 System.Linq; 使用 System.Text; 使用 System.Threading.Tasks;
namespace DocumentManager.RepositoryService
{
internal class MonitorDropFolder
{
public string RepositoryPath { get; set; }
public FileSystemWatcher Watcher { get; set; }
public MonitorDropFolder ()
{
Watcher = new FileSystemWatcher();
Watcher.Path = @"c:\Repository\DropLocation";
Watcher.NotifyFilter = NotifyFilters.FileName;
Watcher.Filter = "*.docx";
Watcher.Created += new FileSystemEventHandler(OnCreatedHandler);
StartMonitoring();
}
public void StartMonitoring()
{
Watcher.EnableRaisingEvents = true;
}
public void StopMonitoring()
{
Watcher.EnableRaisingEvents = false;
}
private void OnCreatedHandler(object source, FileSystemEventArgs e)
{
if(e.ChangeType == WatcherChangeTypes.Created)
{
//don't process temporary files
if (Path.GetFileName(e.FullPath).Substring(0, 1) == "~" || Path.GetFileName(e.FullPath).Substring(0, 1) == "$")
return;
var result = convert(e.FullPath, GetDocStatus(e.Name)).Result;
FileService.MoveNativeToDraft(e.FullPath);
}
}
private async Task<bool> convert(string fileName, string docStatus)
{
try
{
ConvertWordToPDF convertor = new ConvertWordToPDF();
var task = Task.Run(()=>convertor.Convert(fileName, docStatus));
await task;
return true;
}
catch (Exception)
{
return false;
}
}
}
}
提前致谢
更新: 我这样调用代码...
public static void MoveIntoRepository(string sourceFile)
{
string destinationDir = @"C:\Repository\DropLocation\";
var result = MoveFileAsync(sourceFile, Path.Combine(destinationDir, Path.GetFileName(sourceFile))).Result;
}
我也试过像这样绕过文件锁...
bool isFileLocked = isLocked(filename);
int numTries = 0;
while(isFileLocked)
{
numTries++;
if (numTries > 100)
throw new Exception("FileLock Error");
///the following is actually in a called method
byte[] byteArray = File.ReadAllBytes(filename);
///... rest of code here
Thread.Sleep(500);
isFileLocked = isLocked(filename);
}
调用此方法
private static bool isLocked(string filename)
{
try
{
FileStream st = new FileStream();
st = File.Open(filename,FileMode.Open);
st.Close();
return false;
}
catch (Exception)
{
return true;
throw;
}
}
在代码下面查看我的评论:
using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))
{
using(FileStream destinationStream = File.Create(destinationFileName))
{
try
{
await sourceStream.CopyToAsync(destinationStream);
// The sourceFileName file is locked since you are inside the
// the using statement. Move statement for deleting file to
// outside the using.
File.Delete(sourceFileName);
return true;
}
catch
{
return false;
}
}
}
// Move it here