Веские причины для передачи путей в виде строк вместо использования DirectoryInfo / FileInfo - PullRequest
16 голосов
/ 20 марта 2009

В моем новом коде я не использую строки для передачи путей к каталогам или имен файлов. Вместо этого я использую DirectoryInfo и FileInfo, поскольку они, похоже, содержат много информации.

Я видел много кода, который использует строки для передачи информации каталога, затем они "разделяют" и "mid" и "instr" в длинных непонятных выражениях, пока не получают ту часть каталога, которую ищут.

Есть ли веская причина для передачи путей в виде строк?

Ответы [ 6 ]

11 голосов
/ 20 марта 2009

В общем, я думаю, что лучше хранить информацию в FileInfo / DirectoryInfo. В этих классах есть много полезных функций, а также безопасность, связанная с тем, что гораздо проще проверить наличие файла, посмотреть исходно указанный файл и т. Д.

Единственное место, где я (потенциально) мог бы передать путь в виде строки вместо использования FileInfo и DirectoryInfo, если бы путь должен был быть передан через домены приложений или между процессами и т. Д.

FileInfo и DirectoryInfo отлично работают через границы AppDomain (так как они сериализуемы), но в этой ситуации у них довольно много накладных расходов. Если что-то идет вперед и назад, это может оказать влияние.

Однако в этом случае я бы использовал FileInfo и DirectoryInfo, если только я не обнаружил заметную проблему во время профилирования и пытался уменьшить количество сериализованных данных. Если бы у меня не было проблем с производительностью, я бы использовал эти классы, поскольку они обеспечивают большую безопасность и функциональность.

5 голосов
/ 20 марта 2009

DirectoryInfo и FileInfo ужасно тяжелы для передачи, если вам нужен только путь. Я был бы более обеспокоен "сплит и середина и инст" мусор. Изучите способы:

Path.GetFileName
Path.GetDirectoryName
Path.Combine
и т.д ...

Это из класса System.IO.Path, кстати.

5 голосов
/ 20 марта 2009

Если путь указан в приложении (т. Е. Не в простом текстовом файле конфигурации), нет веской причины.

Единственное время (я могу подумать), что это может быть полезно, - это взаимодействие с кодом, который принимает только пути в виде строк.

0 голосов
/ 28 июля 2018

Следует иметь в виду одно существенное различие между строкой пути и FileInfo, которое можно обобщить в следующих тестах:

FileInfo отражает информацию о файле с момента его создания - его можно удалить / изменить, и FileInfo не будет это отражать.

[TestMethod]
        public void TestFileInfo()
        {
            var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
            File.WriteAllText(path, "All your base are belong to us!");
            var file = new FileInfo(path);

            Assert.IsTrue(file.Exists);
            File.Delete(file.FullName);
            Assert.IsTrue(file.Exists);
            Assert.IsFalse(File.Exists(file.FullName));
        }

  [TestMethod]
        public void TestFileInfo()
        {
            var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
            File.WriteAllText(path, "All your base are belong to us!");
            Thread.Sleep(1000);

            var file = new FileInfo(path);
            var date = DateTime.UtcNow;

            Assert.IsTrue(file.LastWriteTimeUtc< date);

            File.WriteAllText(path, "No!");
            Assert.IsTrue(File.GetLastWriteTimeUtc(file.FullName)> date);

            Assert.IsFalse(file.LastWriteTimeUtc > date);
        }

Это может вводить в заблуждение, и если ваш код передает FileInfos вместо строк, вы можете увидеть неправильные результаты для таких свойств, как Exists или Last[..]Time - что не произойдет, если вы будете использовать File.Get[...]() методы.

Однако, с другой стороны, вам также не следует полагаться на метод File.Exists () - поскольку файл можно создать / удалить сразу после запуска тестов. Правильный способ для этого - НЕ делать эту проверку, а скорее принять, что он может вызвать исключение ввода-вывода (и быть готовым обработать это правильно). Подробнее в этой замечательной статье https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/

Кроме того, существенный «плюс» FileInfo / DirectoryInfo заключается в том, что он защищает ваш метод (и потребителей метода) от этого:

void SaveEntity(Entity theThing, string path)
{
    //now, based on the signature, you don't know whether you need file path or directory path

}

//void SaveEntity(Entity theThing, DirectoryInfo path) {}
//void SaveEntity(Entity theThing, FileInfo path) {}
0 голосов
/ 09 сентября 2010

Я думаю, вам нужен класс для инкапсуляции пути к файлу или каталогу, вместо использования необработанных строк и манипулирования ими с помощью статического класса System.IO.Path. Тем не менее, Я не считаю DirectoryInfo и FileInfo подходящими , потому что они, кажется, предназначены скорее для выполнения манипуляций с файлами / каталогами вместо операций пути. Если вы создаете собственный класс для манипулирования путями, вы можете предоставить более удобную для пользователя функциональность манипулирования путями .

0 голосов
/ 15 декабря 2009

Я столкнулся с проблемами при передаче FileInfo в DMZ. Насколько я вижу - поправьте меня, если я ошибаюсь - FileInfo выполняет проверку прав доступа при десериализации, и это не сработает из DMZ и приведет к «пути не найдены». Вместо этого создайте и передайте пользовательский объект с данными, которые вы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...