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

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

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

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


person user79755    schedule 20.03.2009    source источник


Ответы (6)


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

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

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

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

person Reed Copsey    schedule 20.03.2009
comment
Обратите внимание, что вам нужно будет создать новую FileInfo/DirectoryInfo, если файл изменил свое существование или изменил временные метки. - person sighol; 08.09.2016

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

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

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

person Chris    schedule 20.03.2009
comment
Помните, когда вы передаете экземпляр функции, она передает копию ссылки, а не копию всего объекта! Итак, все, что вы действительно передаете, это копия указателя... - person John Rasch; 20.03.2009
comment
Я считаю, что проблема не в том, сколько байт передается, а скорее в накладных расходах на использование FileInfo/DirectoryInfo, которые должны проверять файл различными способами для кэширования информации о нем. - person Steven Sudit; 18.09.2009

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

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

person Sean Bright    schedule 20.03.2009

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

person Dimitri C.    schedule 09.09.2010

Следует иметь в виду одно существенное различие между строкой пути и 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) {}
person Bartosz    schedule 28.07.2018

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

person magnus    schedule 15.12.2009