如何解决如何克服PathTooLongException?
| 因此,我正在编写一个程序,该程序将扫描计算机上的重复文件,因为我看到的程序确实很慢,并且/或者占用了内存,但是当我尝试整个驱动器时遇到了“ 0”。在用C#代码阅读PathTooLongException之后,我对以下两个问题感到好奇。 如果每次更改级别时都切换当前目录,是否会损害性能? 是否有更好的方法来获取所有文件的目录结构(也许通过调用诸如tree.exe之类的东西然后对其进行解析)?解决方法
看到这个图书馆!
.NET Base Class Libraries : Long Path
,还是自己做
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
[DllImport(\"kernel32.dll\",CharSet = CharSet.Unicode)]
internal static extern IntPtr FindFirstFile(string lpFileName,out
WIN32_FIND_DATA lpFindFileData);
[DllImport(\"kernel32.dll\",CharSet = CharSet.Unicode)]
internal static extern bool FindNextFile(IntPtr hFindFile,SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FindClose(IntPtr hFindFile);
// Assume dirName passed in is already prefixed with \\\\?\\
public static IEnumerable<string> EnumerateEntries(string directory)
{
WIN32_FIND_DATA findData;
IntPtr findHandle = FindFirstFile(dirName + @\"\\*\",out findData);
try
{
if (findHandle != INVALID_HANDLE_VALUE)
{
bool found;
do
{
string currentFileName = findData.cFileName;
// if this is a directory,find its contents
if (((int)findData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) != 0)
{
if (currentFileName != \".\" && currentFileName != \"..\")
{
foreach(var child in FindFilesAndDirs(
Path.Combine(dirName,currentFileName))
{
yield return child;
}
}
}
yield return Path.Combine(dirName,currentFileName);
// find next
found = FindNextFile(findHandle,out findData);
}
while (found);
}
}
finally
{
// close the find handle
FindClose(findHandle);
}
}
我尚未验证此代码,显然不是所有类型都已定义,但是它应该为我们指明正确的方向。
,纯C#需要进行优化,但无需使用外部库或调用p / p。即可获得领先优势。
public static class DirectoryEx
{
static char driveLetter;
static string longPath;
static List<string> directories;
static DirectoryEx()
{
longPath = String.Empty;
}
private static char GetAvailableDrive()
{
var all = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\".ToCharArray().Reverse();
var occupied = DriveInfo.GetDrives()
.OrderByDescending(d => d.Name)
.Select(d => (char)d.Name.ToUpper().First());
var free = all.Except(occupied).First();
return free;
}
public static List<string> GetDirectories(string path)
{
directories = new List<string>();
// recursive call
FindDirectories(path);
return directories;
}
static void FindDirectories(string path)
{
try
{
foreach (var directory in Directory.GetDirectories(path))
{
var di = new DirectoryInfo(directory);
if(!String.IsNullOrEmpty(longPath))
directories.Add(di.FullName.Replace(driveLetter + \":\\\\\",longPath + \"\\\\\"));
else
directories.Add(di.FullName);
FindDirectories(di.FullName);
}
}
catch (UnauthorizedAccessException uaex) { Debug.WriteLine(uaex.Message); }
catch (PathTooLongException ptlex)
{
Debug.WriteLine(ptlex.Message);
longPath = path;
Task t = new Task(new Action(() =>
{
CreateVirtualDrive(longPath);
FindDirectories(driveLetter + \":\\\\\");
DeleteVirtualDrive();
longPath = String.Empty;
}));
if (!String.IsNullOrEmpty(longPath))
t.RunSynchronously();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
static void CreateVirtualDrive(string path)
{
driveLetter = GetAvailableDrive();
Process.Start(new ProcessStartInfo() {
FileName = \"cmd.exe\",WindowStyle = ProcessWindowStyle.Hidden,Arguments = String.Format(\"/c subst {0}: {1}\",driveLetter.ToString(),path)
});
while (!DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter))
{
System.Threading.Thread.Sleep(1);
}
}
static void DeleteVirtualDrive()
{
Process.Start(new ProcessStartInfo()
{
FileName = \"cmd.exe\",Arguments = String.Format(\"/c subst {0}: /D\",driveLetter.ToString())
});
while (DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter))
{
System.Threading.Thread.Sleep(1);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。