#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 IEnumerableGetRelativeFolderContents (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"; Listfiles = 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 ) { //Что-то делаешь }
Комментариев нет:
Отправить комментарий