4

I have a problem with getting a final file name in c#.

For example:

If user types two filenames:

"asd." and "asd.."

or

"asd " and "asd  " (two spaces)

then method Path.GetFileName returns "asd.", "asd..", "asd ", "asd  " (two spaces).

After saving it on a hard drive (e.g. using StreamWriter), then there is only one file "asd"

How can I check the final name of the input file? I suppose there is a lot of other examples and I could never do it properly manually.

Edit:

I use it to compare two file names and GetFileName returns: for a.txt - a.txt for A.txt - A.txt

But after save it's the same file. The comparison must ignore case.

AdamF
  • 2,501
  • 17
  • 30
  • Show me your code, so that we can see that and help you – Sanu Uthaiah Bollera Mar 13 '14 at 08:40
  • 3
    I don't think the close vote is justified. It is a legit question about programming and there really is no need for any example code. The question is quite clear: when for example a SaveFileDialog reports the filename as "ads..." and saves it, the file will be renamed by the OS to "ads". How can you determine that this has happened? – John Willemse Mar 13 '14 at 08:55
  • 3
    Interesting question. The behavior is not (obviously) documented in msdn's references. It's certainly possible to create a file with trailing spaces in its name as far as NTFS (or FAT32?) are concerned, I just did it in a cygwin shell. But the explorer appears to handle the filenames as the same file and refuses to rename it when I try to add a space ("source and destination are the same file"). Resembles the incoherent case handling which can bother Java developers under Windows. – Peter - Reinstate Monica Mar 13 '14 at 09:07
  • @Adam You should really consider marking Ulugbek as the correct answer to your question, he really nailed it – samy Mar 13 '14 at 13:50

3 Answers3

4

There is interesting internal NormalizePath method in Path class in .Net. If you don't mind reflection, you can use it.

string fileName = "asd..";
MethodInfo normalizePathMathod = typeof(Path).GetMethod("NormalizePath", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(string), typeof(bool) }, null);
string normalizedFilePath = (string)normalizePathMathod.Invoke(null, new object[] { fileName, true });
string normalizedFileName = Path.GetFileName(normalizedFilePath);

Just found better solution, without reflection. Path.GetFullPath calls NormalizePath method. So we can change it to:

string fileName = "asd..";
string normalizedFilePath = Path.GetFullPath(fileName);
string normalizedFileName = Path.GetFileName(normalizedFilePath);
Ulugbek Umirov
  • 12,719
  • 3
  • 23
  • 31
2

If you use a FileStream to open the file, then you can use the FileStream.Name property after the stream was opened to get the "final" filename.

A crude example:

SaveFileDialog sDlg = new SaveFileDialog();

if (sDlg.ShowDialog() == DialogResult.OK)
{
     // E.g., sDlg.FileName returns "myFile..."
     FileStream f = new FileStream(sDlg.FileName, FileMode.Create);
     Console.WriteLine(f.Name); // then f.Name will return "myFile"
     f.Close();
     Console.ReadLine();
}
sDlg.Dispose();
John Willemse
  • 6,608
  • 7
  • 31
  • 45
0

Under Windows 7 i cannot rename a file from test to test. (it reverts to test) so i think the renaming comes from the filesystem that enforces specific rules for files rather than .Net.

Even using interop calls you cannot create a file with trailing dots. I don't really think you can get the corrected filename from inside .Net. [EDIT: In fact Ulugbek's answer shows a very good way to do it]

A solution may be to write a empty file with the name to a temporary directory and check what the resulting filename is before deleting it.

Here is some more information: Strange behavior from .NET regarding file paths

Community
  • 1
  • 1
samy
  • 14,832
  • 2
  • 54
  • 82