【问题标题】:!File.Exists is not working as expected for filenames containing UTF-8 characters!File.Exists 对于包含 UTF-8 字符的文件名没有按预期工作
【发布时间】:2017-08-21 11:04:47
【问题描述】:

我的控制台应用程序 (C#) 可以完美地处理不包含任何 UTF-8 字符的文件名,但是当文件名包含任何 UTF-8 字符时,我的条件 if(!File.Exists(destFilePath)) 不是按预期工作。

我需要删除那些只存在于目标中而不存在于源中的文件。当我的文件名中有一些特殊字符时,例如,

文件

C:\A00000001\20162350775-Étienne Geoffroy Saint-Hilaire,1772-1844 年,一位富有远见的博物学家。 Hervé Le Guyader.pdf

destFilePath

D:\A00000001\20162350775-Étienne Geoffroy Saint-Hilaire,1772-1844 年,一位富有远见的博物学家。 Hervé Le Guyader.pdf

不应删除上述情况下的文件名,因为源和目标文件名相同,但确实如此。但是对于普通文件名,没有问题。我的代码示例如下:

public void SynchronizeSourceAndDestination(string dir)
        {
            foreach (string file in Directory.GetFiles(dir))
            {
                string destFilePath = file.Replace(BackupDirectory, LookupDirectory);

                if (!File.Exists(destFilePath))
                {
                    // Delete file from Backup
                    File.Delete(file);
                }
            }

            foreach (string directory in Directory.GetDirectories(dir))
            {
                string destinationDirectory = directory.Replace(BackupDirectory, LookupDirectory);

                if (!Directory.Exists(destinationDirectory))
                {
                    Directory.Delete(directory, true);
                    continue;
                }
                SynchronizeSourceAndDestination(directory);
            }
        }

注意:asp.net Web 应用程序具有设置 globalculture="en-US" uiCulture="en-US" requestEncoding="UTF-8" responseEncoding="UTF-8" fileEncoding="UTF -8" 在 web.config 文件中。以上代码是 C# 控制台应用程序,用于处理 Web 应用程序保存的文件。我本地机器中的文件名没有问题,但是当代码在服务器中时,它不起作用。

【问题讨论】:

  • 重命名文件,用 E/e 替换变音符号并再次尝试测试您的假设,该名称不太可能导致问题。请注意,如果服务器上的路径长度超过 ~260 个字符或存在权限问题 Exists() 将返回 false。
  • @Alex K. 长度只有 160 个字符,它给出的问题是因为文件名 É 和 é 中使用了两个字符
  • 如果您在 LookupDirectory 上使用 Directory.GetFiles,并从中获取您感兴趣的文件名,然后在其上使用 ==file 对比,它们是相同的还是不同的? 许多看起来相同的字符实际上是不同的字符。
  • dir 的值是多少? BackupDirectory? LookupDirectory? file.Replace(BackupDirectory, LookupDirectory)?
  • 您的意思是使用!File.Exists 而不是File.Exists

标签: c# .net


【解决方案1】:

这可能与文件路径的长度(>260 个字符)有关,因为 File.Exists 确实适用于 UTF-8 字符。

几分钟前我用 csi.exe 对其进行了测试,输出如下:

C:\Temp>csi
Microsoft (R) Visual C# Interactive Compiler version 2.2.0.61624
Copyright (C) Microsoft Corporation. All rights reserved.

Type "#help" for more information.
> System.IO.File.Exists("C:\\A00000001\\20162350775-Étienne Geoffroy Saint-Hilai
re, 1772-1844 a visionary naturalist. Hervé Le Guyader.pdf")
true
>

如您所见,结果是true。我已经在 Windows 10 机器上测试了这个,荷兰语并安装了 VS2017.2。

--编辑-- 为了完善下面的评论,我创建了这个控制台应用程序进行测试。

using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        private const string BackupDirectory = "C:\\A00000001\\";
        private const string LookupDirectory = "C:\\A00000002\\";
        static void Main(string[] args)
        {
            SynchronizeSourceAndDestination("C:\\A00000001\\");
        }

        public static void SynchronizeSourceAndDestination(string dir)
        {
            foreach (string file in Directory.GetFiles(dir))
            {
                string destFilePath = file.Replace(BackupDirectory, LookupDirectory);

                if (!File.Exists(destFilePath))
                {
                    // Delete file from Backup
                    File.Delete(file);
                }
            }

            foreach (string directory in Directory.GetDirectories(dir))
            {
                string destinationDirectory = directory.Replace(BackupDirectory, LookupDirectory);

                if (!Directory.Exists(destinationDirectory))
                {
                    Directory.Delete(directory, true);
                    continue;
                }
                SynchronizeSourceAndDestination(directory);
            }
        }
    }
}

确保文件夹A00000001A00000002 存在于您的系统中,并在这两个文件夹中放置一个具有相同名称和UTF-8 字符(20162350775-Étienne Geoffroy Saint-Hilaire, 1772-1844 a visionary naturalist. Hervé Le Guyader.pdf) 的文件。

在我的例子中,没有文件因为File.Exists 检查而被删除。

【讨论】:

  • 你是对的,它工作正常,但就我而言,我提供的代码示例,我需要从目标文件夹中获取文件名,并需要检查源文件夹中是否存在此文件名。跨度>
  • 我也测试了你的情况 (C:\\A00000001\\20162350775-Étienne Geoffroy Saint-Hilaire, 1772-1844 a visionary naturalist. Hervé Le Guyader.pdf & destFilePath C:\\A00000002\\20162350775-Étienne Geoffroy Saint-Hilaire, 1772-1844 a visionary naturalist. Hervé Le Guyader.pdf) 仍然得到了预期的结果。没有文件被删除,因为 File.Exists 返回 true。为了确定,还用不同的路径对其进行了测试。
  • 是的,我刚刚在服务器中创建了两个文件夹,它与文件名完美配合。但它给原始文件夹中存在的文件名带来了同样的问题。我没有注意到新文件夹和原始文件夹有任何区别。
  • 可能是权限,如 MSDN 中所述:If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path. 来源:msdn.microsoft.com/en-us/library/…
  • 非常感谢您的宝贵时间。我也认为这是因为我的目标文件夹在 Dropbox 中的一些权限问题。该程序在保管箱内的文件夹之外的其他文件夹中运行良好。
【解决方案2】:

为了使我的解决方案可行,我通过按 É (Alt + 144)、é (Alt + 130) 更改了扩展的 ASCII 字符。我认为这是因为文件创建者直接复制和粘贴了一些字符。

【讨论】:

    猜你喜欢
    • 2019-09-03
    • 1970-01-01
    • 2016-04-24
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 2023-04-03
    • 2013-07-31
    相关资源
    最近更新 更多