7

Somehow a file has appeared in one of my directories, and it has space at the end of its extension - its name is "test.txt ". The weird thing is that Directory.GetFiles() returns me the path of this file, but I'm unable to retrieve file information with FileInfo class.

The error manifests here:

DirectoryInfo di = new DirectoryInfo("c:\\somedir");
FileInfo fi = di.GetFileSystemInfos("test*")[0] as FileInfo; 
//correctly fi.FullName is "c:\somedir\test.txt "
//but fi.Exists==false (!)

Is FileInfo class broken? Can I somehow retrieve information about this file? I really don't know how did that file appear on my file system, and I am unable to recreate some more of them.

All of my attempts to create a new file with this type of extension have failed, but now my program is crashing when encoutering it. I can easily handle the exception when finding the file, but boy am I curious about this!

Axarydax
  • 16,353
  • 21
  • 92
  • 151
  • Have you run an OS disk checker to ensure that its not a corrupted file? Would we be correct to assume that this is under Windows? If so which version? – ChrisBD Apr 30 '10 at 07:12
  • Windows Vista Business x86, but I'm sure I have somehow created the file myself, about a year ago, according to the date – Axarydax Apr 30 '10 at 09:33

3 Answers3

6

Ending file names with a space is documented as a Bad Idea.

From MSDN "Naming Files, Paths, and Namespaces (Windows)":

  • Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not.

Also, the KB article "INFO: Filenames Ending with Space or Period Not Supported":

Problems can arise when a Macintosh client creates a file on a Windows NT server. The code to remove trailing spaces and periods is not carried out and the Macintosh user gets the correctly punctuated filename. The Win32 APIs FindFirstFile() and FindNextFile() return a filename that ends in a space or in a period; however, there is no way to create or open the file using the Win32 API.

DirectoryInfo probably uses FindFirstFile() and friends to produce directory listings. File.Exists is most likely implemented through GetFileAttributes() which probably suffers from the same problem as CreateFile() and will report a nonexistent file.

Hence, not a problem in .NET specifically, but in Windows itself.

AJM
  • 1,317
  • 2
  • 15
  • 30
Thomas
  • 174,939
  • 50
  • 355
  • 478
4

Yes i know of these files. I also got once such a beast thing. To get rid of it i don't know about a programming way in C#, but good old command line is your friend:

Open a console window in the given folder (or execute cmd and navigate to the folder with cd command). Now enter dir /x to retrieve the shortname of the files in this directory. Use this name to delete or rename the file by using the del or ren command.

Oliver
  • 43,366
  • 8
  • 94
  • 151
  • Thank you, Oliver. That dir /x did the trick. I had the same problem and tried deleting the file using the full name + extension but was told the file couldn't be found. However I was finally able to delete it using the shortname. –  Jan 28 '11 at 13:11
  • 1
    You will be able to manipulate these files by bypassing the Win32 API, i.e. through the POSIX subsystem (`cygwin` commands such as `mv` and `touch` will gladly manipulate these filenames) or possibly by prepending the path with L"\\?\" (this will also likely to bypass the Win32 APIs idiosyncrasies.) – vladr Apr 15 '12 at 03:22
  • 1
    @vladr Thanks. Prepending path with "\\?\" for file ending with a space did the trick for WinAPI function `FindFirstFile()`. It might help also with other WinAPI functions. – HiFile.app - best file manager Jan 25 '19 at 08:39
0

You can manipulate files with trailing spaces (among other edge cases) if you use the \\?\ path syntax: \\?\c:\somedir\test.txt .

Luís Oliveira
  • 2,964
  • 1
  • 20
  • 26