2014-03-13 2 views
4

У меня проблема с получением окончательного имени файла в C#.Как получить окончательное имя файла

Например:

Если пользователь два имени:

"ASD" и "ASD .."

или

"ASD" и "ASD  " (два пробела)

затем метод Path.GetFileName возвращает "ASD.", "ASD ..", "ASD", "asd  " (два пробела).

После сохранения его на жестком диске (например, с помощью StreamWriter), то есть только один файл «ASD»

Как можно проверить окончательное имя входного файла? Я полагаю, что есть много других примеров, и я никогда не смог бы сделать это правильно вручную.

Edit:

Я использую его для сравнения двух имен файлов и GetFileName возвращает: для a.txt - a.txt для a.txt - a.txt

Но после того, как сохранить его тот же файл. Сравнение должно игнорировать случай.

+0

Покажите мне код, так что мы можем видеть, что и поможет вам –

+3

я не думаю, что близко голос оправдан. Это законный вопрос о программировании, и действительно нет необходимости в каком-либо примерном коде. Вопрос совершенно ясен: когда, например, SaveFileDialog сообщает имя файла как «ads ...» и сохраняет его, файл будет переименован ОС в «ads».Как вы можете определить, что это произошло? –

+3

Интересный вопрос. Поведение не является (очевидно) документировано в ссылках msdn. Можно, конечно, создать файл с конечными пробелами в имени NTFS (или FAT32?), Я просто сделал это в оболочке cygwin. Но исследователь, похоже, обрабатывает имена файлов как один и тот же файл и отказывается переименовать его, когда я пытаюсь добавить пространство («источник и место назначения - это тот же файл»). Совместим с некогерентной обработкой приложений, которые могут беспокоить Java-разработчиков под Windows. –

ответ

4

Существует интересный внутренний метод NormalizePath в классе Путь в .Net. Если вы не возражаете против размышлений, вы можете использовать его.

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

Просто нашли лучшее решение, без отражения. Path.GetFullPath вызывает метод NormalizePath. Таким образом, мы можем изменить его:

string fileName = "asd.."; 
string normalizedFilePath = Path.GetFullPath(fileName); 
string normalizedFileName = Path.GetFileName(normalizedFilePath); 
+0

Очень приятно, не думал об этом – samy

+0

Да, это очень приятно, спасибо :) – AdamF

+0

Хорошее решение, особенно одно без отражения! –

0

В Windows 7 я не могу переименовать файл из теста для тестирования. (он возвращается к тестированию), поэтому я думаю, что переименование происходит из файловой системы, которая применяет определенные правила для файлов, а не .Net.

Даже используя вызовы interop, вы не можете создать файл с завершающими точками. Я действительно не думаю, что вы можете получить исправленное имя файла изнутри .Net. [РЕДАКТИРОВАТЬ: На самом деле ответ Улугбека показывает очень хороший способ сделать это]

Решение может заключаться в том, чтобы написать пустой файл с именем во временный каталог и проверить, какое результирующее имя файла перед удалением.

Вот еще информация: Strange behavior from .NET regarding file paths

2

Если вы используете FileStream, чтобы открыть файл, то вы можете использовать FileStream.Name свойство после того, как поток был открыт, чтобы получить «окончательное» имя файла.

Грубый пример:

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(); 
Смежные вопросы