Я работаю над проектом. Я должен сравнить содержимое двух файлов и посмотреть, точно ли они соответствуют друг другу.
Перед многими проверками и проверкой ошибок мой первый черновик:
DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + "\\TestArea\\");
FileInfo[] files = di.GetFiles(filename + ".*");
FileInfo outputFile = files.Where(f => f.Extension == ".out").Single<FileInfo>();
FileInfo expectedFile = files.Where(f => f.Extension == ".exp").Single <FileInfo>();
using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
{
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
{
while (!(outFile.EndOfStream || expFile.EndOfStream))
{
if (outFile.ReadLine() != expFile.ReadLine())
{
return false;
}
}
return (outFile.EndOfStream && expFile.EndOfStream);
}
}
Кажется немного странным иметь вложенные using
утверждения.
Есть лучший способ сделать это?
Ответы:
Предпочтительный способ сделать это - поставить открывающую скобку только
{
после последнегоusing
оператора, например так:источник
IDisposable
чтобы звонитьDispose()
дважды, ничего не должны делать. Это правило только в случае плохо написанных одноразовых изделий.Если объекты одного типа, вы можете сделать следующее
источник
IDisposable
объекты из блока using, мы не можем вызвать ни одного из членов класса (без приведения, который побеждает точку imo).Когда
IDisposable
s одного типа, вы можете сделать следующее:На странице MSDN
using
есть документация по этой языковой функции.Вы можете сделать следующее, независимо от того,
IDisposable
относятся ли к одному типу:источник
если вы не возражаете объявить переменные для вашего блока using перед блоком using, вы можете объявить их все в одном выражении using.
Таким образом, x и y - это просто переменные-заполнители типа ID, доступные для использования блоком using, и вы используете t и u внутри своего кода. Просто подумал, что упомяну.
источник
Если вы хотите сравнить файлы эффективно, вообще не используйте StreamReaders, и тогда в использовании нет необходимости - вы можете использовать низкоуровневое чтение потоков, чтобы получить буферы данных для сравнения.
Вы также можете сначала сравнить такие вещи, как размер файла, чтобы быстро обнаружить разные файлы, чтобы избавить себя от необходимости читать все данные тоже.
источник
Оператор using работает с интерфейсом IDisposable, поэтому другим вариантом может быть создание составного класса некоторого типа, который реализует IDisposable и имеет ссылки на все объекты IDisposable, которые вы обычно помещаете в оператор using. Обратной стороной этого является то, что вы должны сначала объявить свои переменные и выходить за пределы области видимости, чтобы они были полезны в блоке using, требуя больше строк кода, чем требовалось бы для некоторых других предложений.
В этом случае конструктор для DisposableCollection является массивом params, поэтому вы можете вводить сколько угодно.
источник
Вы также можете сказать:
Но некоторые люди могут найти это трудно читать. Кстати, как оптимизация вашей проблемы, почему вы не проверяете, что размеры файлов одинаковы, прежде чем переходить строка за строкой?
источник
Вы можете опустить скобки для всех, кроме самых внутренних, используя:
Я думаю, что это чище, чем помещать несколько одинаковых типов в одно и то же использование, как предлагали другие, но я уверен, что многие люди будут думать, что это сбивает с толку
источник
Вы можете сгруппировать несколько одноразовых объектов в один оператор использования с запятыми:
источник
В этом нет ничего странного.
using
это сокращенный способ обеспечения удаления объекта после завершения блока кода. Если у вас есть одноразовый предмет во внешнем блоке, который должен использовать внутренний блок, это вполне приемлемо.Изменить: Слишком медленный набор текста, чтобы показать пример консолидированного кода. +1 всем остальным.
источник
И чтобы просто внести ясность, в этом случае, поскольку каждый последующий оператор является одним оператором (а не блоком), вы можете опустить все квадратные скобки:
источник
Начиная с C # 8.0 вы можете использовать объявление об использовании .
Это избавит от использования переменных в конце области видимости переменных, то есть в конце метода.
источник
Они появляются время от времени, когда я тоже пишу код. Вы могли бы рассмотреть перемещение второго оператора using в другую функцию?
источник
Вы также спрашиваете, есть ли лучший способ сравнить с файлами? Я предпочитаю рассчитывать CRC или MD5 для обоих файлов и сравнивать их.
Например, вы можете использовать следующий метод расширения:
Как только вы это сделаете, сравните файлы довольно просто:
Вы можете использовать встроенный класс System.Security.Cryptography.MD5, но вычисляемый хеш является байтом [], поэтому вам все равно придется сравнивать эти два массива.
источник
Stream
объект и вызыватьReadByte
метод, пока он не вернет -1. Это сэкономит большие объемы памяти для больших файлов.ReadByte
продвижение позиции потока на один байт. Поэтому, если вы продолжите вызывать его, пока он не вернет -1 (EOF), он даст вам каждый байт в файле. msdn.microsoft.com/en-us/library/system.io.stream.readbyte.aspxКроме того, если вы уже знаете пути, нет смысла сканировать каталог.
Вместо этого я бы порекомендовал что-то вроде этого:
Path.Combine
добавит папку или имя файла к пути и удостоверится, что между путем и именем есть только одна обратная косая черта.File.OpenText
откроет файл и создаст заStreamReader
один раз.Приставляя строку к @, вы можете избежать экранирования от обратной косой черты (например,
@"a\b\c"
)источник
Я думаю, что, возможно, нашел синтаксически более чистый способ объявления этого выражения с помощью, и это, кажется, работает для меня? использование var в качестве типа в выражении using вместо IDisposable, по-видимому, динамически выводит тип для обоих объектов и позволяет мне создавать экземпляры обоих моих объектов и вызывать их свойства и методы класса, которому они выделены, как в
using(var uow = new UnitOfWorkType1(), uow2 = new UnitOfWorkType2()){}.
случае, если кто-нибудь знает, почему это не правильно, пожалуйста, дайте мне знать
источник
Это нормальный способ использования и работает идеально. Хотя есть и другие способы реализации этого. Почти каждый ответ уже присутствует в ответе на этот вопрос. Но здесь я перечисляю их всех вместе.
Уже использован
Опция 1
Вариант 2
источник