1

I'm trying to make a map for a game that I'm planning to create. The map should have two data files, and a picture file.

I want to put them together, to form a single file, and I only want to use the default libraries.

How can I do this, and still be able to separate them later?

A solution would be compression, but I couldn't find a way to compress multiple files using the gzipstreamer class.

Tibi
  • 4,015
  • 8
  • 40
  • 64
  • If the files hold related data then why create more than one in the first place? If the data is not related then why not leave the files separated? – Andrei Jun 14 '11 at 20:15
  • @Andrei: The data is in fact collision maps, objects such as trees and where they should be placed and so on. So that I don't corrupt the .png image, they have to be separate files. – Tibi Jun 15 '11 at 07:44

5 Answers5

1

You could use SharpZipLib to create a ZIP file.

M4N
  • 94,805
  • 45
  • 217
  • 260
1

Did you consider embedding the files as resources in the assembly (or in a separate assembly?)

A lot depends on the reasons why you want to group them.

Compression will cost time and CPU power.

Emond
  • 50,210
  • 11
  • 84
  • 115
  • That's not the case here, because maps are opened/created at runtime, by two different applications. First there is the game, and there is the map editor. – Tibi Jun 15 '11 at 07:43
  • In many game production lines/tool sets, while in production the files are kept separate and at the end of the line the resources are packed for distribution. There is no reason to unpack when deployed. It is very similar to code that gets compiled and not shipped. – Emond Jun 15 '11 at 11:11
0

Gzip compression only works on one file (it only ever has). You could try ZIP, 7-ZIP or some other archive format that allows multiple files. Alternately you can TAR the files together first, which was common practice for the compression scheme Gzip was invented to replace.

Broam
  • 4,602
  • 1
  • 23
  • 38
0

I had a simiar question a while ago here about saving 2 XML files in one file.

See my answer with code.

"I ended up writing my own Stream, which can be thought of as a multistream. It allows you to treat one stream as multiple streams in succession. i.e. pass a multistream to an xml parser (or anything else) and it'll read up to a marker, which says 'this is the end of the stream'. If you then pass that same stream to another xml parser, it'll read from that marker, to the next one or EOF"

Your basic usage would be:

Writing:
    Open File Stream
    Create MultiStream passing in File Stream in constructor
    Write data file to multistream
    Call write end of stream marker on multistream
    Write 2nd data file to multistream
    Call write end of stream marker on multistream
    Save picture to multistream
    Close multistream
    Close file stream

Reading:
    Open File Stream
    Create MultiStream passing in File Stream in constructor
    Read data file
    Call advance to next stream on multistream
    Read 2nd data file
    Call advance to next stream on multistream
    Read image (Image.FromStream() etc.)
    Close multistream
    Close file stream
Community
  • 1
  • 1
George Duckett
  • 31,770
  • 9
  • 95
  • 162
0

I think you should consider embedding the resources in the assembly as Erno suggests.

But if you really want to pack them into a single file, you could do so by simply writing the length of each stream before the stream itself. You could then read the length byte and afterwards return the next length bytes as a Stream. Reading/writing with ugly methods below. The target stream could eventually be gzipped. Note that the naive methods below reads and writes the entire string to a single buffer and assumes that no file is larger than int.MaxValue.

But I would not recommend using just the standard libraries.

    static void Append(Stream source, Stream target)
    {
        BinaryWriter writer = new BinaryWriter(target);
        BinaryReader reader = new BinaryReader(source);  
        writer.Write((long)source.Length);
        byte[] buffer = new byte[1024];
        int read;
        do
        {
            read = reader.Read(buffer, 0, buffer.Length);
            writer.Write(buffer, 0, read);
        }
        while (read > 0);
        writer.Flush();
    }

    static Stream ReadNextStream(Stream packed)
    {
        BinaryReader reader = new BinaryReader(packed);
        int streamLength = (int)reader.ReadInt64();

        MemoryStream result = new MemoryStream();
        byte[] buffer = new byte[streamLength];
        reader.Read(buffer, 0, buffer.Length);

        BinaryWriter writer = new BinaryWriter(result);
        writer.Write(buffer, 0, buffer.Length);
        writer.Flush();

        result.Seek(0, SeekOrigin.Begin);
        return result;
    }
faester
  • 14,886
  • 5
  • 45
  • 56
  • Thanks, but as I already commented on the above post... the maps are created and opened at runtime, and are needed by two different application. – Tibi Jun 15 '11 at 07:46
  • Well, ok, but I don't see how that would prohibit storing the files in a single file as described. Hope you find something useful elsewhere :) – faester Jun 15 '11 at 08:08
  • That was about embedding the file into the assembly. But I did manage to combine them, by writing the length of each file at the beginning, and then the data of each file. Thanks :) – Tibi Jun 15 '11 at 09:33