Запись файла из streamа ресурсов сборки на диск

Я не могу найти более эффективный способ «скопировать» встроенный ресурс на диск, а не следующее:

using (BinaryReader reader = new BinaryReader( assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext"))) { using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create))) { long bytesLeft = reader.BaseStream.Length; while (bytesLeft > 0) { // 65535L is < Int32.MaxValue, so no need to test for overflow byte[] chunk = reader.ReadBytes((int)Math.Min(bytesLeft, 65536L)); writer.Write(chunk); bytesLeft -= chunk.Length; } } } 

Кажется, нет более прямого способа сделать копию, если я не пропущу что-то …

Я не уверен, почему вы используете BinaryReader / BinaryWriter . Лично я бы начал с полезной утилиты:

 public static void CopyStream(Stream input, Stream output) { // Insert null checking here for production byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, bytesRead); } } 

затем назовите его:

 using (Stream input = assembly.GetManifestResourceStream(resourceName)) using (Stream output = File.Create(path)) { CopyStream(input, output); } 

Конечно, вы можете resize буфера или использовать его как параметр для метода, но главное, что это более простой код. Это более эффективно? Неа. Вы действительно хотите, чтобы этот код был более эффективным? У вас на самом деле есть сотни мегабайт, которые нужно записать на диск?

Я считаю, что мне редко нужен код, чтобы быть ультраэффективным, но мне почти всегда нужно, чтобы он был простым. Разница в производительности, которую вы можете видеть между этим и «умным» подходом (если она доступна) вряд ли будет эффектом, изменяющим сложность (например, O (n) – O (log n)) – и это тот тип производительности, который действительно может стоить гоняться.

EDIT: Как отмечалось в комментариях, .NET 4.0 имеет Stream.CopyTo поэтому вам не нужно сами это кодировать.

Если ресурс (файл) является двоичным.

 File.WriteAllBytes("C:\ResourceName", Resources.ResourceName); 

И если ресурс (файл) – это текст.

  File.WriteAllText("C:\ResourceName", Resources.ResourceName); 

Я фактически использовал эту единственную строку: Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create)) . Конечно, это для .Net 4.0

Обновление: я обнаружил, что вышеприведенная строка может заблокировать файл таким образом, что SQLite сообщает, что firebase database доступна только для чтения. Поэтому я получил следующее:

 Using newFile As Stream = New FileStream(FileLocation, FileMode.Create) Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(newFile) End Using 

Лично я бы сделал это так:

 using (BinaryReader reader = new BinaryReader( assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext"))) { using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create))) { byte[] buffer = new byte[64 * 1024]; int numread = reader.Read(buffer,0,buffer.Length); while (numread > 0) { writer.Write(buffer,0,numread); numread = reader.Read(buffer,0,buffer.Length); } writer.Flush(); } } 

Вам нужно будет написать цикл, если это ваш вопрос. Но вы могли обойтись без читателя и писателя, поскольку основной stream уже имеет дело с байтовыми данными.

Это примерно так же компактно, как я могу получить:

 using (Stream inStream = File.OpenRead(inputFile)) using (Stream outStream = File.OpenWrite(outputFile)) { int read; byte[] buffer = new byte[64 * 1024]; while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, read); } } 
  • Как записывать веб-камеру и аудио с помощью webRTC и одноранговое соединение на сервере
  • Как передать указатель на массив с помощью p / invoke в C #?
  • Использовать Visual Studio 2012 и компилироваться со старым набором инструментов платформы?
  • Несколько уровней в пользовательской маршрутизации MVC
  • Межпроцессная связь для Windows на C # (.NET 2.0)
  • «Const» означает только чтение или что-то еще?
  • Инъекция зависимостей - требуется новый экземпляр для нескольких методов classов
  • Редактирование редактирования сквозных нитей
  • О том, как распознать ссылку Rvalue или Lvalue и правило if-it-have-a-name
  • Как преобразовать объект в массив байтов в C #
  • Почему двоичный вывод не равен при компиляции снова?
  • Давайте будем гением компьютера.