C # - Самый простой способ разобрать имя файла с пробелами, например. "C: \ Test \ File with spaces.txt" - PullRequest
8 голосов
/ 07 декабря 2009

Я пытаюсь передать полный путь к файлу в FFMPEG.

C:\TestFolder\Input\Friends - Season 6 - Gag Reel.avi

и, очевидно, ему не нравится тот факт, что в пути есть пробелы, ошибочно выглядящие так:

C:\TestFolder\Input\Friends: no such file or directory

Так, каков самый простой способ использовать имена файлов с пробелами в них? Должен ли я просто заменить все пробелы символами ~ или есть лучший способ? Я попытался экранировать строку с различными символами:

@"C:\TestFolder\Input\Friends - Season 6 - Gag Reel.avi";

Но это не работает. Есть ли хитрость в сохранении пробелов?

Ответы [ 6 ]

33 голосов
/ 07 декабря 2009

Единственный раз, когда вам обычно приходится выполнять какую-либо специальную обработку имен файлов с пробелами, - это когда вы передаете их внешним инструментам или форматам. Например, если вы создаете список аргументов для внешнего исполняемого файла, все, что вам нужно сделать, это указать путь:

string path = @"C:\TestFolder\Input\Friends - Season 6 - Gag Reel.avi";
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "program.exe";
psi.Arguments = "\"" + path + "\""; // escape the quotes

... что приведет к этой командной строке:

program.exe "C: \ TestFolder \ Input \ Friends - Season 6 - Gag Reel.avi "

7 голосов
/ 07 декабря 2009

System.IO. Путь предоставляет несколько методов для управления именами файлов ...

5 голосов
/ 07 декабря 2009

вы используете FileInfo класс?

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

используйте как
FileInfo f = new FileInfo(fullPathEvenWithSpaces);

4 голосов
/ 08 января 2010

Я согласен с вышеуказанным постом. Чтобы сделать это проще, вот код, который вам нужно использовать. В My Humble Opinion единственным хорошим именем файла является имя файла без пробелов.

Для этого в коде c # у меня есть это:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint GetShortPathName(
   [MarshalAs(UnmanagedType.LPTStr)]
    string lpszLongPath,
   [MarshalAs(UnmanagedType.LPTStr)]
    StringBuilder lpszShortPath,
   uint cchBuffer);

public static StringBuilder shortNameBuffer = new StringBuilder(256);
public static string ToShortPathName(string longName)
{
  uint result = GetShortPathName(longName, shortNameBuffer, 256);
  return shortNameBuffer.ToString();
}

Это добавляет метод к вашему классу, который можно использовать следующим образом:

String goodFileName = ToShortPathName (evilFileName);

ПРИМЕЧАНИЕ: я использую это в пользовательском интерфейсе, так что я не против того, чтобы не поддерживать потоки и повторно использовать StringBuider Если вы находитесь в многопоточной среде, убедитесь, что вы извлекаете распределение StringBuilder внутри вашего метода.

4 голосов
/ 07 декабря 2009

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

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

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

Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.StartInfo.Arguments = string.Format("\"{0}\"", filePath);
p.Start();
0 голосов
/ 07 декабря 2009

Все файлы имеют короткий путь, совместимый с DOS 8.3. Единственный способ получить это имя файла - GetShortPathName. Лучшее объяснение, которое я могу найти, находится по следующему адресу:

http://www.pinvoke.net/default.aspx/kernel32.GetShortPathName

...