2012-05-02 3 views
16

В моем приложении я компилировать другую программу из source.cs файла с помощью CodeDom.Compiler и я вставлять некоторые ресурсы (EXE и DLL-файлы) во время компиляции с помощью:Как прочитать встроенный ресурс как массив байтов, не записывая его на диск?

// .... rest of code 

if (provider.Supports(GeneratorSupport.Resources)) 
{ 
    cp.EmbeddedResources.Add("MyFile.exe"); 
} 
if (provider.Supports(GeneratorSupport.Resources)) 
{ 
    cp.EmbeddedResources.Add("New.dll"); 
} 
// ....rest of code 

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

File.ReadAllBytes("extractedfile.exe"); 
File.ReadAllBytes("extracteddll.dll"); 

Я делаю это после извлечения двух файлов на диск с помощью этой функции:

public static void ExtractSaveResource(String filename, String location) 
{ 
    // Assembly assembly = Assembly.GetExecutingAssembly(); 
    System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); 
    // Stream stream = assembly.GetManifestResourceStream("Installer.Properties.mydll.dll"); // or whatever 
    // string my_namespace = a.GetName().Name.ToString(); 
    Stream resFilestream = a.GetManifestResourceStream(filename); 
    if (resFilestream != null) 
    { 
     BinaryReader br = new BinaryReader(resFilestream); 
     FileStream fs = new FileStream(location, FileMode.Create); // say 
     BinaryWriter bw = new BinaryWriter(fs); 
     byte[] ba = new byte[resFilestream.Length]; 
     resFilestream.Read(ba, 0, ba.Length); 
     bw.Write(ba); 
     br.Close(); 
     bw.Close(); 
     resFilestream.Close(); 
    } 
    // this.Close(); 
} 

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

ответ

23

Вы на самом деле уже читаете поток в массив байтов, почему бы просто не остановиться?

public static byte[] ExtractResource(String filename) 
{ 
    System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); 
    using (Stream resFilestream = a.GetManifestResourceStream(filename)) 
    { 
     if (resFilestream == null) return null; 
     byte[] ba = new byte[resFilestream.Length]; 
     resFilestream.Read(ba, 0, ba.Length); 
     return ba; 
    } 
} 

Редактировать: Просмотреть комментарии для предпочтительного образца для чтения.

+1

Обновлен мой ответ, нет необходимости в потоке памяти, когда вы уже читаете поток в массив байтов. – Rotem

+2

Это может работать некорректно, потому что 'Stream.Read()' может не возвращать все данные в одном 'Read()'. Я не уверен, как этот специфический «поток» ведет себя, но чтобы быть в безопасности, я бы использовал для этого «MemoryStream», «CopyTo()», а затем использовал «ToArray()». – svick

+0

@svick: Вы правы. В качестве альтернативы можно использовать шаблон чтения, описанный в примере на этой странице: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx – Rotem

Смежные вопросы