2012-05-02 11 views
16

W mojej aplikacji kompilacji innego programu z pliku source.cs korzystając CodeDom.Compiler i osadzić niektórych zasobów (pliki EXE i DLL) w czasie kompilacji przy użyciu:Jak odczytywać zasób osadzony jako tablicę bajtów bez zapisywania ich na dysku?

// .... 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 

W skompilowanego pliku, muszę przeczytać zasoby osadzone jako tablica bajtów. Teraz robię to poprzez wydobycie zasobów na dysku za pomocą funkcji poniżej oraz wykorzystanie

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

Robię to po wyodrębnieniu dwóch plików na dysku za pomocą tej funkcji:

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(); 
} 

Jak mogę Zrób to samo (pobierz zasoby osadzone jako tablicę bajtów), ale bez zapisywania czegokolwiek na dysku twardym?

Odpowiedz

23

Już teraz czytasz strumień do tablicy bajtów, dlaczego nie po prostu się tam zatrzymać?

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; 
    } 
} 

edytuj: Zobacz komentarze do preferowanego wzoru czytania.

+1

Zaktualizowałem moją odpowiedź, nie trzeba strumienia pamięci, gdy już czytasz strumień do tablicy bajtów. – Rotem

+2

Może to nie działać poprawnie, ponieważ 'Stream.Read()' może nie zwracać wszystkich danych w jednym 'Read()'. Nie jestem pewien, jak zachowuje się ten specyficzny "Stream", ale aby być po bezpiecznej stronie, użyłbym '' MemoryStream', 'CopyTo()' do tego, a następnie użyj 'ToArray()'. – svick

+0

@svick: Masz rację. Alternatywnie można użyć wzorca czytania opisanego w przykładzie na tej stronie: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx – Rotem

Powiązane problemy