Question

I'm currently developing a game and I was wondering if it's possible to make a custom file packer/unpacker/modifier in C#

Where it can pack all files in a whole directory including sub-directories in a single file with a custom extension, and it can unpack all the files but still having the same information when it was packed, and modify files inside a packed file.

I know I'm asking for a lot and I'm not hoping to get all the answers so please if you know at least one, please tell me and or direct me to a link if there is any.

Please and Thank You.

Was it helpful?

Solution

to create a pack file, and be able to read from it, you need to first have a definition of how you are going to store information within that pack file, so you would first need to create a struct or a class.

class FileEntry
{
  public int FileOffset { get; set; }
  public int FileSize { get; set; }
  public int Flags { get; set; }
  public String FileName { get; set; }
  public String FileDirectory { get; set; }
}

For creating

You would be best tagging your file so that you can verify that it is the correct file type, ie. setting the first 4 bytes to something like "PACK" (you should have the pack file opened with a StreamWriter.

You would need to open your root directory of the directory tree you wish to pack and iterate through all sub directories and files and for each file found, create a FileEntry and store that in a list. The next thing you should write to the file would be a 32bit int that specifies the total number of files within the pack (the Count property of your list).

You would then want to iterate through your list of FileEntry and write another tag to specify a file start, such as "FILE", then the 32bit int of FileSize, 32bit int of Flags, and then, a 32bit it of the string length of FileName as FileName is dynamic and can be of any length, then write out the FileName string its self, and the same with FileDirectory length and FileDirectory string. After you have written FileDirectory string, you would then want to write the file data its self, note that this is not stored within the file entry as you probably dont want all this data to be stored within memory.

Once you have done that for everything in your FileEntry list, you can then close the file, and that will be all those files packed up neatly into a single custom pack file.

For Reading

We will essentially be doing the same thing, but we will be reading, rather than writing, and you will have to record an offset value so that you are able to track where a new file starts so that you can read its data out later on.

You would first need to read in the first 4 bytes of the file and test that they are set as "PACK", if they are we can continue as this is our file. Next, read in the next 4 bytes and covert to a 32bit integer so we can get the total number of files contained within this pack.

You can then run a for loop, something like for(int i=0; i<g_max_files; i++) to make things easier while we are looking for our FileEntry's, remembering to increment our offset every time we read anything via our StreamReader. The first thing we check in our loop is the first 4 bytes after the file out match "FILE". If they match we then read out in 4 byte (32bit) chunks, FileSize, then Flags and then FileName's length, once we know FileName's length, we can read out FileName its self and repeat with FileDirectory. If you have been increasing the offset specified earlier, you should now have the file position in bytes of where the file data starts for this particular file, you can now create a new FileEntry and set all of the properties and add it to your file list and allow the loop to continue back to the next file.

Modifying

With modifying, if you are going to be INCREASING the file size of any of the files within the pack, you are going to have to recreate the pack, if you are decreasing the file size of any of the files, you can simply alter the FileSize int and pad the existing file data within the pack with null's.

If you are looking to leave the existing files as they are, but only add to the end, you are simply doing a modification of both reading, and creating. You just add on to the end of the pack you already have by using the creating part of this, and alter the total files int at the top of the file.

Hope this was helpful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top