ZetCode

C# PathTooLongException

最后修改于 2025 年 4 月 20 日

本教程解释了在 C# 中处理 PathTooLongException 的方法,当处理超过系统限制的文件路径时。 当路径名对于文件系统来说太长时,会发生此异常。

PathTooLongException 类表示当路径或文件名超过系统定义的最大长度时抛出的异常。 在 Windows 中,最大路径长度通常为 260 个字符。

PathTooLongException 继承自 IOException,并且是 System.IO 命名空间的一部分。 它指示与路径相关的操作由于路径长度限制而失败。

PathTooLongException 基础示例

此示例演示了尝试创建路径超过系统限制的文件时,如何发生 PathTooLongException。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            string longPath = @"C:\" + new string('x', 300);
            File.Create(longPath);
        }
        catch (PathTooLongException ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            Console.WriteLine("Path length exceeded system limits.");
        }
    }
}

该代码尝试创建一个路径超过 300 个字符的文件。 这会在大多数 Windows 系统上触发 PathTooLongException。 该示例展示了如何捕获和处理这种特定类型的异常。

异常消息提供了有关错误的详细信息。 catch 块通过显示一条信息性消息来优雅地处理异常。 这种模式对于健壮的文件系统操作至关重要。

在操作之前检查路径长度

此示例展示了如何在执行文件操作之前主动检查路径长度,以避免 PathTooLongException。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = @"C:\temp\" + new string('a', 250);
        
        if (path.Length > 260)
        {
            Console.WriteLine("Path is too long. Maximum allowed is 260 characters.");
            Console.WriteLine("Current length: " + path.Length);
            return;
        }

        try
        {
            Directory.CreateDirectory(path);
            Console.WriteLine("Directory created successfully.");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }
}

该代码在尝试创建目录之前检查路径长度。 这种预防性方法通过首先验证约束来避免异常。 该示例使用简单的长度检查来对照 Windows 限制。

虽然 260 个字符是传统的 Windows 限制,但较新的系统可能通过适当的配置支持更长的路径。 该检查提供了针对常见情况的基本保护。

使用 UNC 前缀处理长路径

此示例演示了如何在支持的 Windows 系统上使用 UNC 前缀来处理长路径。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string longPath = @"\\?\" + @"C:\temp\" + new string('b', 300);
        
        try
        {
            Directory.CreateDirectory(longPath);
            Console.WriteLine("Long path directory created.");
        }
        catch (PathTooLongException ex)
        {
            Console.WriteLine("Still too long: " + ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Other error: " + ex.Message);
        }
    }
}

UNC 前缀 (\\?\) 允许 Windows 上的路径最多为 32,767 个字符。 此示例尝试创建一个具有非常长路径的目录。 该前缀绕过了传统的 260 个字符的限制。

请注意,并非所有 Windows API 都支持 UNC 路径。 必须在清单或注册表中配置应用程序以支持长路径。 此技术在较新的 Windows 版本上效果最佳。

在文件操作中使用 PathTooLongException

此示例展示了 PathTooLongException 如何在各种文件操作期间发生,例如读取或写入文件。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string longFilePath = @"C:\" + new string('d', 250) + @"\file.txt";
        
        try
        {
            string content = File.ReadAllText(longFilePath);
            Console.WriteLine("File read successfully.");
        }
        catch (PathTooLongException)
        {
            Console.WriteLine("Cannot read file - path too long.");
        }
        catch (DirectoryNotFoundException)
        {
            Console.WriteLine("Directory not found.");
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("File not found.");
        }
    }
}

该示例尝试读取具有长路径的文件。 捕获了多种异常类型以处理不同的失败场景。 PathTooLongException 专门针对路径长度问题进行捕获。

这种模式演示了正确的异常处理层次结构。 应该在更通用的异常之前捕获更具体的异常。 该代码为每种错误情况提供适当的反馈。

使用相对路径

此示例展示了当相对路径与当前目录路径组合时,也可能触发 PathTooLongException。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string relativePath = new string('e', 300) + ".txt";
        
        try
        {
            string fullPath = Path.GetFullPath(relativePath);
            Console.WriteLine("Full path: " + fullPath);
            
            if (fullPath.Length > 260)
            {
                throw new PathTooLongException(
                    "Combined path exceeds maximum length");
            }
            
            File.WriteAllText(relativePath, "Test content");
        }
        catch (PathTooLongException ex)
        {
            Console.WriteLine("Path too long: " + ex.Message);
        }
    }
}

该代码演示了相对路径如何与当前目录组合。 显式检查完整路径长度以防止异常。 这种方法可以更好地控制路径长度验证。

该示例展示了当业务逻辑检测到无效状态时手动引发异常。 与来自框架方法的自动异常相比,此技术可以提供更多上下文。

在递归方法中处理 PathTooLongException

此示例演示了在递归文件系统操作中处理 PathTooLongException 的方法,其中路径可能变得太长。

Program.cs
using System;
using System.IO;

class Program
{
    static void ProcessDirectory(string path, int depth)
    {
        try
        {
            foreach (var file in Directory.GetFiles(path))
            {
                Console.WriteLine(file);
            }
            
            foreach (var dir in Directory.GetDirectories(path))
            {
                ProcessDirectory(dir, depth + 1);
            }
        }
        catch (PathTooLongException)
        {
            Console.WriteLine($"Skipping long path at depth {depth}");
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine($"Access denied at depth {depth}");
        }
    }

    static void Main()
    {
        string startPath = @"C:\Program Files";
        ProcessDirectory(startPath, 0);
    }
}

递归目录处理方法包括对 PathTooLongException 的特定处理。 这可以防止整个操作在遇到一个无效路径时失败。

该示例展示了如何在出现异常的情况下保持操作的连续性。 深度跟踪有助于诊断目录树中出现问题的位置。 这种模式对于健壮的文件系统扫描器非常有用。

自定义路径缩短方案

此示例实现了一种自定义路径缩短方案,以避免 PathTooLongException,同时保留功能。

Program.cs
using System;
using System.IO;

class Program
{
    static string GetShortenedPath(string basePath, string relativePath)
    {
        string fullPath = Path.Combine(basePath, relativePath);
        
        if (fullPath.Length = 260)
        {
            return fullPath;
        }
        
        // Custom shortening logic
        string[] parts = relativePath.Split(Path.DirectorySeparatorChar);
        string shortened = "";
        
        foreach (string part in parts)
        {
            if (part.Length > 8)
            {
                shortened += part.Substring(0, 6) + "~" + Path.DirectorySeparatorChar;
            }
            else
            {
                shortened += part + Path.DirectorySeparatorChar;
            }
        }
        
        shortened = shortened.TrimEnd(Path.DirectorySeparatorChar);
        return Path.Combine(basePath, shortened);
    }

    static void Main()
    {
        string basePath = @"C:\temp";
        string longRelative = new string('f', 50) + Path.DirectorySeparatorChar + 
                            new string('g', 50) + Path.DirectorySeparatorChar + 
                            "file.txt";
        
        string safePath = GetShortenedPath(basePath, longRelative);
        Console.WriteLine("Original length: " + 
            Path.Combine(basePath, longRelative).Length);
        Console.WriteLine("Shortened length: " + safePath.Length);
        Console.WriteLine("Shortened path: " + safePath);
    }
}

自定义路径缩短算法在保留路径结构的同时缩短组件长度。 此示例演示了一种使长路径易于管理的简单方法。

该解决方案将每个路径组件修剪为 6 个字符加上一个波浪号。 更复杂的算法可以使用哈希或数据库查找。 此技术展示了如何在系统限制范围内创造性地工作。

来源

PathTooLongException 类文档

本教程涵盖了在 C# 中处理 PathTooLongException,包括预防技术、解决方法以及用于长路径的自定义解决方案。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程