【问题标题】:File paths with non-ascii characters and FileInfo in C#C# 中具有非 ascii 字符和 FileInfo 的文件路径
【发布时间】:2009-08-19 06:36:38
【问题描述】:

我得到一个或多或少看起来像这样的字符串:

"C:\\bláh\\bleh"

我用它创建了一个 FileInfo,但是当我检查它的存在时它返回 false:

var file = new FileInfo(path);
file.Exists;

如果我手动将路径重命名为

"C:\\blah\\bleh"

在调试时并确保 blah 存在且其中包含 bleh,然后 file.Exists 开始返回 true。所以我认为问题出在非 ascii 字符上。

实际的字符串是由我的程序构建的。一部分来自应用程序的 AppDomain,即包含“á”的部分,另一部分在某种程度上来自用户。这两部分由 Path.Combine 组合在一起。我通过两种方式确认了结果字符串的有效性:将它从我的程序生成的错误(包括路径)复制到资源管理器中,打开文件就好了。在调试器中查看该字符串,它看起来正确转义,因为 \ 被写为 \。 “á”由调试器按字面意思打印。

我应该如何处理一个字符串,即使它有非 ascii 字符,它也会变成一个有效的路径?

【问题讨论】:

  • 字符串从何而来;它是编码到代码文件中还是由用户提供?
  • Fredrik Mörk,我刚刚将该信息添加到问题本身。
  • 这很奇怪。我创建了一个具有相同路径和名称的文件,下面的代码打印出"True"FileInfo fi = new FileInfo("C:\\bláh\\bleh"); Console.WriteLine(fi.Exists);
  • 您的应用生成的“á”代码是什么?这个字符的代码是什么,如果从路径中获取它(找到“C:\”上的所有文件夹,找到这个特定的文件夹并查看调试代码)?

标签: c# unicode path fileinfo


【解决方案1】:

这是一种处理文件名中变音符号的方法。 File.Exists 方法的成功取决于您的系统如何存储文件名。

public bool FileExists(string sPath)
{
  //Checking for composed and decomposed is to handle diacritics in filenames.  
  var pathComposed = sPath.Normalize(NormalizationForm.FormC);
  if (File.Exists(pathComposed))    
      return true;

   //We really need to check both possibilities.
   var pathDecomposed = sPath.Normalize(NormalizationForm.FormD);
   if (File.Exists(pathDecomposed))     
      return true;

   return false;
}

【讨论】:

    【解决方案2】:

    试试这个

        string sourceFile = @"C:\bláh\bleh";
        if (File.Exists(sourceFile))
        {
    
             Console.WriteLine("file exist.");
    
        }
        else
        {
            Console.WriteLine("file does not exist.");
    
        }
    

    注意:Exists 方法不应用于路径验证,该方法仅检查路径中指定的文件是否存在。将无效路径传递给 Exists 会返回 false。

    对于路径验证,您可以使用 Directory.Exists。

    【讨论】:

    • 我不是要验证路径,我想确保文件确实存在。
    【解决方案3】:

    我刚刚手动创建了一个 bláh 文件夹,其中包含一个 bleh 文件,并且就位后,此代码将按预期打印 True

    using System;
    using System.IO;
    
    namespace ConsoleApplication72
    {
        class Program
        {
            static void Main(string[] args)
            {
                string filename = "c:\\bláh\\bleh";
    
                FileInfo fi = new FileInfo(filename);
    
                Console.WriteLine(fi.Exists);
    
                Console.ReadLine();
            }
        }
    }
    

    我建议检查您的字符串的来源 - 特别是,尽管您的 3k 代表反对这是问题所在,但请记住,将反斜杠表示为 \\ 是 C# 语法的产物,并且您要确保您的字符串实际上只包含一个 \s。

    【讨论】:

    • 字符串来自其他地方,我只是使用 Path.Combine 向其中添加更多内容。当我打印字符串时,它看起来像 c:\bláh\bleh,我可以将其复制并粘贴到资源管理器的文件路径文本框中,然后它会打开文件。当我在调试器中查看它时,我看到了 c:\\bláh\\bleh,所以我相信这个字符串实际上是正确的。稍后我将尝试像您一样在控制台应用程序中执行此操作,看看会发生什么。
    【解决方案4】:

    参考@adatapost 的回复,无效文件名字符列表(从System.IO.Path.GetInvalidFileNameChars() 收集,实际上不包含带有变音符号的普通字符。

    看起来您真正要问的问题是“How do I remove diacritics from a string(或在本例中为文件路径)?”。

    或者你可能不是在问这个问题,而是真的想找到一个文件名:

    c:\blòh\bleh
    

    (或类似的东西)。在这种情况下,您需要尝试打开一个具有相同名称的文件,并且不是 c:\bloh\bleh

    【讨论】:

    • 我想处理文件 c:\bláh\bleh,而不是 c:\blah\bleh。我用 c:\blah\bleh 尝试了我的程序,只是为了验证“á”是问题所在。如果我以任何方式更改路径,我最终会指向一个不存在的文件,因为路径是正确的(我可以将其复制并粘贴到资源管理器中,然后打开正确的文件)。
    【解决方案5】:

    看起来路径中的“bleh”是一个目录,而不是一个文件。要检查文件夹是否存在,请使用 Directory.Exists 方法。

    【讨论】:

      【解决方案6】:

      问题是:程序没有足够的权限来访问该文件。修复权限解决了问题。似乎当我没有进行实验时,我以某种方式设法重现了权限问题,可能是通过手动创建没有非 ascii 字符的文件夹并复制另一个。

      哦……好尴尬。

      【讨论】:

        猜你喜欢
        • 2018-06-21
        • 1970-01-01
        • 2020-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多