Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Как получить путь относительно базового каталога в C#?

#c_sharp


В проекте на WinForms имеется набор отчетов, расположенных в папке и её подпапках,
например:

D:\Shared\Common\BaseReports\Main.rpt
D:\Shared\Common\BaseReports\Main_new.rpt
D:\Shared\Common\BaseReports\2015\Payments.rpt
D:\Shared\Common\BaseReports\2016\Payments.rpt


и т.д.
Само приложение может располагаться где угодно, а путь к отчетам в нём указывается
через переменную string reportPath = "D:\\Shared\\Common\\BaseReports";

В дальнейшем пусть путь к конкретному отчету задается с использованием базовой папки,
например, так: string someReport = reportPath + "\\2015\\Payment.rpt";

Как получить список папок и файлов, находящихся внутри D:\Shared\Common\BaseReports\
в виде:

Main.rpt
Main_new.rpt
2015\Payments.rpt
2016\Payments.rpt


... ?

Да, про string.Replace() [string relativePath = someReport.Replace(reportPath, "");]
знаю, но может быть есть способ лучше?
Спасибо!
    


Ответы

Ответ 1



Как то так. var baseDir = new DirectoryInfo("H:\\...\\Reports"); foreach(var file in baseDir.EnumerateFiles("*.rpt",SearchOption.AllDirectories)) { Console.WriteLine(file.FullName.Replace(baseDir.FullName + Path.DirectorySeparatorChar, string.Empty)); } Работает с любой глубиной вложенных папок. Минимум должен быть доступ на чтение для файлов и папок, в противном случае будет исключение, но если это пользовательская папка и программа может писать туда отчеты с правами пользователя, то проблем с доступом быть не должно (диверсия пользователя не в счет). Выводит правильные системные слеши в путях. Работает быстрее чем с использованием Directory.GetFiles()

Ответ 2



В качестве модификации ответа @rdorn небольшая вариация на тему: public static IEnumerable GetRelativeFolderContents (string folder, string searchPattern = "*") { //Проверки на валидность параметров if (!Directory.Exists(folder)) { //Нет пути для сканирования содержимого директории throw new IOException("Путь \"" + folder + "\" не существует."); } //Проверяем наличие разделителя папок в конце базового пути, и, если его нет - добавляем. if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) folder += Path.DirectorySeparatorChar; //Список для результата: List result = new List(); //Временная переменная: string t = ""; //Получаем содержимое базового пути, включая все вложенные папки и файлы: foreach (var item in Directory.EnumerateFileSystemEntries(folder, "*", SearchOption.AllDirectories)) { t = item.Replace(folder, string.Empty); //Проверяем, не ссылку ли на папку мы получили? if (Directory.Exists(item)) { //Папка пустая? if (!Directory.EnumerateFileSystemEntries(item).Any()) { //Если пустая - добавляем к результату (не пустые папки сами добавятся вместе с //путями к файлам, в них содержащимся) if (!item.EndsWith(Path.DirectorySeparatorChar.ToString())) { result.Add(t + Path.DirectorySeparatorChar); } else { result.Add(t); } } } else { result.Add(t); } } return result; } Основные отличия - незначительные, а именно - дополнительные проверки и использование Directory.EnumerateFileSystemEntries, и, как следствие, в результат выборки попадут пустые папки, если они есть и параметры поиска допускают это. Будет работать в .NET 4.0 и выше.

Ответ 3



Если приложение планируется использовать без VS. То можно использовать "Получение пути к директории исполняемого файла" new FileInfo(String.Concat(Assembly.GetExecutingAssembly().Location)).Directory.FullName и в нем уже произвести поиск файлов с расширением .rpt А если приложение будет работать только с VS то можно использовать EnvDTE. Поиск и фильтр файлов можно сделать как в ручную так и с помощью структуры DirectoryInfo. Если совсем до мануала не добраться, могу написать как. Пишу как: static void Main(string[] args) { string root = @"D:\Trash"; List files = Directory.GetFiles(@"D:\Trash", "*.cpp", SearchOption.AllDirectories).ToList(); List relPath = new List(); foreach (var file in files) { relPath.Add(file.Replace(root,"")); Console.WriteLine(file.Replace(root, "")); } }

Ответ 4



Не проще тогда использовать стандартную папку %appdata% и хранить все свои данные в ней? string Path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string someReport = Path + "\\Shared\\Common\\BaseReports\\"; А чтобы найти файлы, нужно пробежаться по всем папкам вот пример: string file; string[] inf = Directory.GetFiles( someReport, "*.rpt", SearchOption.AllDirectories ); foreach ( var info in inf ) { //Что-то делаешь }

Комментариев нет:

Отправить комментарий