我需要检查文件(通过UNC path
在远程服务器上)是否存在(这里的权限不是问题;我需要进行模拟等)。
我使用CreateFileW函数创建file handle
。
我也尝试过GetFileAttributesEx,但是行为是相同的。
HANDLE CreateFileW(
LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
如果我处理
UNC paths
,由于UNC cache(不同的进程会复制或删除我需要检查的文件),可能会导致错误的结果。它取决于
FileNotFoundCacheLifetime
注册表项的值(默认情况下,该值为10秒)。// lets say I would like to check a file
// in the beginning the file exists
// than another process delete this file
// (e.g. executing drop database command by sql server)
// than another process copies this file back
// and all steps above takes less then FileNotFoundCacheLifetime value
// path = @"\\server\C$\Tmp\Folder\database\myDb.mdf"
private static void Test(string path)
{
File.Exists(path); //exists
Directory.Exists(Path.GetDirectoryName(path)); //exists
using (var handle = CreateFile(path, EFileAccess.GenericRead, EFileShare.Read, IntPtr.Zero,
ECreationDisposition.OpenExisting, EFileAttributes.Normal, IntPtr.Zero))
{
if (handle == null || handle.IsInvalid)
{
//FileNotFoundCacheLifetime = 0 => exists
//FileNotFoundCacheLifetime = 10 => Win32Exception - The system cannot find the file specified
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
}
}
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern SafeFileHandle CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
#region CreateFile
[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}
[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}
public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5,
}
[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
#endregion CreateFile
您知道如何获得未缓存的结果吗?
基本上,我可以禁用我知道的
UNC cache
。在这里,我需要一种不同的方法-如何针对特定的方法调用准确地获取未缓存的结果。
我知道以下方法-
$NOCSC$
(@"\\server$NOCSC$\C$\folder\file"
)修饰符,但不幸的是,它不适用于所有操作系统。File.Exists()
和Folder.Exists()
可以工作,但是我需要fileapi
,因为它支持长路径(基本上,这只是一个可行的解决方案)。对我来说,另一个好的解决方案是以编程方式清理UNC文件系统缓存(再次精确地在特定方法调用之前)。
最佳答案
在blogs mdsn上有一条针对长路径的修复程序(根据您对这篇文章的评论),它是.net 4.6.2及更高版本的申请人。
您将必须将应用程序 list 文件项添加到您的项目中,博客中提供了有关该过程的详细指南,但对于所有人而言,这似乎是一个很好的解决方案,而没有任何必要的麻烦。
在示例中,他们确实在控制台应用程序上对其进行了测试,因此您将必须确定如何对解决方案进行适当的调整。
关于c# - 如何指定createfilew函数获取未缓存的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57020034/