Alex
Alex

Reputation: 1367

How to open a file with a name consisting of spaces?

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:

Upvotes: 1

Views: 881

Answers (2)

Jacob Ewald
Jacob Ewald

Reputation: 2178

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();
    }
}

Upvotes: 3

Jacob Ewald
Jacob Ewald

Reputation: 2178

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.

Upvotes: 1

Related Questions