微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何克服PathTooLongException?

如何解决如何克服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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?