如何打开名称由空格组成的文件?

发布于 2024-10-30 16:17:56 字数 856 浏览 1 评论 0原文

这个问题类似于我的另一个问题( GetDirectories无法枚举名称为 #255 的文件夹的子文件夹)。

在我的 C# 3.5 .NET 应用程序中,我尝试使用打开文件

using (FileStream fileStream = 
new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

但是,如果文件名类似于“”,则代码会失败并出现异常

类型的第一次机会异常 'System.IO.DirectoryNotFoundException' 发生在 mscorlib.dll 中 信息: 找不到部分 路径“C:\Temp\”。

是否可以使用.NET方式打开此类文件?

PS 这不是人为的情况(就像有人怀疑我之前的问题一样),这样的文件可以通过流行的软件完美创建,例如如果您创建一个名称仅由空格组成的邮件文件夹,Thunderbird 可以创建这样的文件。

要重现,请执行以下步骤:

  • 下载并安装 Far Commander 或 Mozilla Thunderbird
  • 在 Far 创建一个名为“ ”的文件。在 Thunderbird 中,在您的邮件帐户中创建一个名为“ ”的子文件夹,
  • 尝试使用上面的代码打开名为“ ”的文件

The question is similar to another my question ( GetDirectories fails to enumerate subfolders of a folder with #255 name ).

In my C# 3.5 .NET application I am trying to open a file using

using (FileStream fileStream = 
new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

However, if a file name is like " ", the code fails with the exception

A first chance exception of type
'System.IO.DirectoryNotFoundException'
occurred in mscorlib.dll Additional
information: Could not find a part of
the path "C:\Temp\ ".

Is it possible to open such file with .NET means or not?

P.S. This is not artificial situation (like someone suspected for my previous question), such file can be perfectly created by popular software, e.g. Thunderbird can create such file if you create a mail folder with a name consisting of spaces only.

To reproduce, do the following steps:

  • Download and install Far Commander or Mozilla Thunderbird
  • In Far create a file with a name " ". In Thunderbird, create a subfolder in your mail account with a name " "
  • Try to open a file named " " using the code above

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁虫ゝ 2024-11-06 16:17:56

看起来访问文件的典型 .Net 方式不会考虑特殊字符。我最初的答案是假设文件名是空格,但我现在发现您打算将其设置为 Alt+255 字符。以下是使用 Win32 API 打开文件的示例控制台应用程序:

class Program
{
    public const UInt32 GENERIC_ALL = 0x10000000;
    public const UInt32 GENERIC_READ = 0x80000000;
    public const UInt32 GENERIC_WRITE = 0x40000000;
    public const UInt32 GENERIC_EXECUTE = 0x20000000;
    public const UInt32 FILE_SHARE_READ = 0x00000001;
    public const UInt32 FILE_SHARE_WRITE = 0x00000002;
    public const UInt32 CREATE_ALWAYS = 2;
    public const UInt32 CREATE_NEW = 1;
    public const UInt32 OPEN_ALWAYS = 4;
    public const UInt32 OPEN_EXISTING = 3;
    public const UInt32 TRUNCATE_EXISTING = 5;

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string lpFileName, System.UInt32 dwDesiredAccess, System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);

    static void Main(string[] args)
    {
        Microsoft.Win32.SafeHandles.SafeFileHandle oSafeHandle = CreateFile(@"Path to your folder\ ", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        using (FileStream oFS = new FileStream(oSafeHandle, FileAccess.Read))
        {
            Console.WriteLine("file was opened");
        }

        Console.ReadLine();
    }
}

It appears that the typical .Net way of accessing files won't account for the special character. My initial answer was assuming that the file name was a space, but I see now that you intended for it to be the Alt+255 character. Here's a sample Console app that uses the Win32 API to open the file:

class Program
{
    public const UInt32 GENERIC_ALL = 0x10000000;
    public const UInt32 GENERIC_READ = 0x80000000;
    public const UInt32 GENERIC_WRITE = 0x40000000;
    public const UInt32 GENERIC_EXECUTE = 0x20000000;
    public const UInt32 FILE_SHARE_READ = 0x00000001;
    public const UInt32 FILE_SHARE_WRITE = 0x00000002;
    public const UInt32 CREATE_ALWAYS = 2;
    public const UInt32 CREATE_NEW = 1;
    public const UInt32 OPEN_ALWAYS = 4;
    public const UInt32 OPEN_EXISTING = 3;
    public const UInt32 TRUNCATE_EXISTING = 5;

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string lpFileName, System.UInt32 dwDesiredAccess, System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);

    static void Main(string[] args)
    {
        Microsoft.Win32.SafeHandles.SafeFileHandle oSafeHandle = CreateFile(@"Path to your folder\ ", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        using (FileStream oFS = new FileStream(oSafeHandle, FileAccess.Read))
        {
            Console.WriteLine("file was opened");
        }

        Console.ReadLine();
    }
}
心舞飞扬 2024-11-06 16:17:56

Windows 要求您指定文件名,您不能创建名称只有一个空格的文件。 Windows 命名约定

您需要首先创建一个具有有效名称的文件,然后在代码中引用该文件。

Windows requires you to specify a filename, you can't create a file with a name of just a single space. Windows Naming Conventions

You'll need to first create a file with a valid name, then reference that in your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文