因此,我正在编写一个程序,它将扫描计算机上的重复文件,因为我看到的程序非常慢,而且/或内存占优势,但是当我尝试整个驱动器时,我遇到了一个PathTooLongException。在阅读了PathTooLongException in C# code之后,我对以下两个问题感到好奇。
如果每次更改级别时切换当前目录,
发布于 2012-05-23 07:56:43
看这个图书馆!
.NET Base Class Libraries : Long Path
发布于 2014-11-18 16:03:34
或者自己动手,
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, out
WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll", 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);
}
}我还没有验证这段代码,而且显然并不是所有的类型都定义好了,但是它应该会为我们指明正确的方向。
发布于 2016-03-04 15:06:19
纯C#,需要优化,但可以在不使用外部库或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",
WindowStyle = ProcessWindowStyle.Hidden,
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);
}
}
}https://stackoverflow.com/questions/6119505
复制相似问题