1

Hi im trying to extract a file from my embedded resource but the issue is that the file size is not correct, it should be around 3500KB but it comes out as 5850KB or so.

            Assembly ^myAssembly = Assembly::GetExecutingAssembly();
        Stream ^myStream = myAssembly->GetManifestResourceStream("cool.exe");
        FileStream^ fs = gcnew FileStream("cool.exe",FileMode::Append,FileAccess::Write,FileShare::Write);
        StreamReader^ Reader = gcnew StreamReader(myStream);
        StreamWriter^ Writer = gcnew StreamWriter(fs);
        Writer->Write(Reader->ReadToEnd());
        fs->Close();

This is the edited one:

Assembly ^myAssembly = Assembly::GetExecutingAssembly();
        Stream ^myStream = myAssembly->GetManifestResourceStream("cool.exe");
        FileStream^ fs = gcnew FileStream("cool.exe",FileMode::Append,FileAccess::Write,FileShare::Write);
        StreamReader^ Reader = gcnew StreamReader(myStream);
        StreamWriter^ Writer = gcnew StreamWriter(fs);
        //Writer->Write(Reader->ReadToEnd());

        array<Byte^>^ buffer = gcnew array<Byte^>(256);

        while (true)
        {

            int read = Reader->Read(buffer,0,buffer->Length);
            if(read <= 0)
            {
                return;
            }
            Writer->Write(buffer,0,read);
        }

        fs->Close();

SOLOUTION

public: static void CopyStream(Stream^ input, Stream^ output) 
        {     

            array<Byte>^ buffer = gcnew array<Byte>(32768);

            long TempPos = input->Position; 

            while (true)         
            {         
                int read = input->Read(buffer, 0, buffer->Length);         
                if (read <= 0) break;         
                output->Write (buffer, 0, read);     
            }     
            input->Position = TempPos;// or you make Position = 0 to set it at the start 
        }

Then to use it:

Assembly ^myAssembly = Assembly::GetExecutingAssembly();
        Stream ^myStream = myAssembly->GetManifestResourceStream("cool.exe");
        FileStream^ fs = gcnew FileStream("cool.exe",FileMode::Append,FileAccess::Write,FileShare::Write);

        CopyStream(myStream,fs);
        fs->Close();

This will make the correct file and correct file size =)

cccru
  • 13
  • 3

1 Answers1

2

Binary data isn't text.

The StreamReader is converting your data to UTF8, which isn't what you want.
You need to copy the raw bytes by calling Write and Read.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • could you link me to some documentation? Would I have to use BinaryWriter? – cccru Jul 24 '11 at 17:27
  • No. Just call `Read()` until it reads `0`, and `Write()` each block that you read. http://www.google.com/search?q=.net+copy+stream&ie=UTF-8 – SLaks Jul 24 '11 at 17:39
  • Ok i edited my post, am i going in the right direction? I am getting 1 error: Error 1 error C2664: 'void System::IO::TextWriter::Write(cli::array ^,int,int)' : cannot convert parameter 1 from 'cli::array ^' to 'cli::array ^' – cccru Jul 24 '11 at 17:54
  • You aren't dealing with text; you cannot use a `StreamWriter`. You need to write directly to the stream. http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c – SLaks Jul 24 '11 at 18:07
  • Ah ok so i used Stream instead and I still end up with the same error as above. – cccru Jul 24 '11 at 19:31