gpt4 book ai didi

c# - 删除/创建文件在多次迭代后抛出 System.UnauthorizedAccessException

转载 作者:行者123 更新时间:2023-11-30 17:27:40 25 4
gpt4 key购买 nike

在测试有关写入/创建/删除文件的一些事情时,我编写了以下程序,循环删除和创建文件 n 次。

static string path = @"C:\Users\Remy\Desktop\Testing";
static readonly int sampleSize = 10000; // Amount of iterations the methods will be run for.

static byte[] sourceFile;

static void Main(string[] args)
{
using (FileStream fs = new FileStream(path + @"\SourceFile.txt", FileMode.Open, FileAccess.Read))
{
sourceFile = new byte[fs.Length];
fs.Read(sourceFile, 0, sourceFile.Length);
}

string filePath = path + @"\Destination.txt";
for (int i = 0; i < sampleSize; i++)
{
if (File.Exists(filePath))
{
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);//Error sometimes throws here.
}

using (FileStream file = File.OpenWrite(filePath))
{
file.Write(sourceFile, 0, sourceFile.Length);
}
}

Console.ReadLine();
}

当迭代次数不太高(大约 1000 次)时,此程序大部分时间都按预期运行。它将删除旧文件并创建一个新文件。

然而,当我将迭代次数增加到 10000/100000 时,问题出现在极少数情况下(大约 0.03% 的时间),它在 using (FileStream file = File.OpenWrite(filePath)),同时在其他 99.97% 的时间内成功通过。当错误抛出时,文件不会被创建。

这在使用调试/发布的 VS(作为管理员)中以及在以管理员身份运行的构建 .exe 中都会发生。

在查看此问题时,我发现了以下有关 Unauth... 异常的答案。

  • this答案建议设置属性,但如我的示例所示,我已经这样做了。
  • this和其他一些答案建议使用管理员权限运行应用程序。我已经在做这件事了。

我还添加了父文件夹的权限,以允许 完全控制 到所有文件和子文件夹的 Everyone

起初我想也许我正在创建的文件不够大(目前写入 976kb 的随机数据)并且由于某种原因程序迭代创建/删除的速度比操作系统/硬盘可以处理的更快。但是增加文件大小时会发生相同的行为

我已经在 3 台机器上对其进行了测试,并且在所有机器上都发生了这种情况。

这可能是 Windows 因误报而抛出异常的情况吗?看到它只发生在大的迭代中吗?我在这里错过了完全不同的东西吗?

注意:我不是在寻找处理异常的方法。我能应付。我正在寻找发生这种奇怪行为的原因为什么,以及如果可能防止而不是治愈


环境

我要写入的磁盘是 Crucial MX300 SSD,使用没有 RAID 的 sata 3。 16 GB 内存。操作系统 Windows 10(专业版)64 位。运行程序时,系统尽可能空闲。

控制台应用程序针对 .NET Framework 4.6.1 构建,使用 Visual Studio 2017 和 Release Any CPU 设置。


我根据评论建议尝试的其他事情:

我尝试在创建和删除后添加一个 Thread.Sleep 以确保 Windows 能够清除文件缓存。这仍然会抛出异常,但这次它会在 File.Delete(filePath); 上抛出异常。 代替。

关闭 Windows Defender 等也会产生在 File.Delete(filePath) 而不是 using(FIleStream....) 上抛出错误的结果。

改为使用以下内容写入文件:

using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.None)) 
{
file.Write(sourceFile, 0, sourceFile.Length); file.Flush(flushToDisk: true);
}

也产生同样的异常被抛出

最佳答案

这种问题是没法解决的,唯一的办法就是预防或避免,如果操作失败,做一些日志。如果失败,请多次尝试这样的操作。之前我已经创建了一个,这里是代码片段。

public IList<string> ReadLineByLineFromFile( string filePath )
{
const int numberOfRetries = 3;
const int delayOnRetry = 500;

bool success = false;
List<string> logs = null;

for ( int i = 0; i <= numberOfRetries && success == false; i++ )
{
try
{
logs = new List<string>();

const Int32 bufferSize = 128;
using ( var fileStream = File.Open( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) )
using ( var streamReader = new StreamReader( fileStream, Encoding.UTF8, true, bufferSize ) )
{
string line;

while ( ( line = streamReader.ReadLine() ) != null )
{
logs.Add( line );
}
}

success = true;
}
catch ( IOException ex ) when ( i < numberOfRetries )
{
Local.Instance().Logger.Warn( ex, "Retrying reading logs from file path {0}, retry count {1} with dealy {2} ms.", filePath, i + 1,
delayOnRetry );

System.Threading.Thread.Sleep( delayOnRetry );
}
}

GC.Collect();

return logs;
}

关于c# - 删除/创建文件在多次迭代后抛出 System.UnauthorizedAccessException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54530134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com