Click here to Skip to main content
15,896,557 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
How would I (in C# .net) pack multiple files on my hard drive into a DAT file, and also unpack into individual files again?

The files to be added to the DAT file will be selected in a list box, so reading to byte arrays and serialazing will not work.

[Serializable]
public class MyObject : ISerializable
{
//The byte arrays would have to be listed here. I don't see a way to do that, because the program wont know what files to
//pack until runtime when they are selected in the list box.
  public byte[] byteArray1;  public int n2;
  public byte[] bytaArray2;
  public byte[] byteArray3;



Please correct me if im wrong about that.
Posted
Updated 2-May-11 12:15pm
v6
Comments
NuttingCDEF 2-May-11 16:27pm    
Can you give an example? What have you tried already? Any error messages / problems encountered?

Hi there,

You know of serializing one class, or rather one object. Then you say, there are multiple files to be written into one file, hence you cannot use that approach. I'd say you just know the answer and how to do it (or rather you possess the capacity to do it) but you are way too lazy to do it.

No offense, but if that is the case, development is not for you :) Anyways, here you go, it just took me 3 minutes to write this code up and 1 search in Google to know what I would want :S Frankly, typing and formatting this answer took me longer :D lol

First off all, an overview of the answer posted below: All I have done is put all information of the files that I want into one class and SERIALIZE that class. Yes, simple like that.
C#
using System;
using System.Runtime.Serialization;

namespace Objects.Serialization
{
    [Serializable()]
    class SelectedFileInfo : ISerializable
    {
        #region Variable(s) & Propert(y/ies)

        public string fileName;
        public byte[] fileData;

        #endregion

        #region Constant(s)

        private const string FileNameField = "FileName";
        private const string FileDataField = "FileData";

        #endregion

        #region Constructor(s)

        public SelectedFileInfo()
        {
            this.fileName = string.Empty;
            this.fileData = null;
        }

        public SelectedFileInfo(SerializationInfo info, StreamingContext context)
        {
            this.fileName = info.GetString(SelectedFileInfo.FileNameField);
            this.fileData = (byte[])info.GetValue(SelectedFileInfo.FileDataField, typeof(byte[]));
        }

        #endregion

        #region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            this.retrieveObjectData(info, context);
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            this.retrieveObjectData(info, context);
        }

        private void retrieveObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(SelectedFileInfo.FileNameField, this.fileName);
            info.AddValue(SelectedFileInfo.FileDataField, this.fileData);
        }

        #endregion
    }
}

This class is what actually contains the data of the file you want, I've only put 2 members in the class, but you can add or remove anything you want, based on your needs. Create an object of this class and put data into it for each file that you have (So if you have, 5 files >> 5 objects, 2 files >> 2 objects, etc.).
C#
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Objects.Serialization
{
    [Serializable()]
    class SelectedFileHolder : ISerializable
    {
        #region Variable(s) & Propert(y/ies)

        public List<selectedfileinfo> fileList; 

        #endregion

        #region Constant(s)

        private const string FileListField = "FileList";

        #endregion

        #region Constructor(s)

        public SelectedFileHolder()
        {
            this.fileList = new List<selectedfileinfo>();
        }

        public SelectedFileHolder(SerializationInfo info, StreamingContext context)
        {
            this.fileList = (List<selectedfileinfo>)info.GetValue(SelectedFileHolder.FileListField, typeof(List<selectedfileinfo>));
        }

        #endregion

        #region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            this.retrieveObjectData(info, context);
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            this.retrieveObjectData(info, context);
        }

        private void retrieveObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(SelectedFileHolder.FileListField, this.fileList);
        }

        #endregion
    }
}


This is the class which would contain all the SelectedFileInfoobjects you created and it is this class that we are going to serialize and de-serialize. I.e. the SelectedFileInfo objects that created for each file are added to an instance of this class.

If you still don't get it, look into the example I've created below.
C#
// Creating the objects
SelectedFileHolder holder = new SelectedFileHolder();

SelectedFileInfo file1 = new SelectedFileInfo();
file1.fileData = File.ReadAllBytes(@"C:\wamp\license.txt");
file1.fileName = "License Data";
holder.fileList.Add(file1);

// You can add as much as you want, because I have used a List instead of a fixed size array

MessageBox.Show(string.Format("{0} : {1}", holder.fileList[0].fileName, holder.fileList[0].fileData.Length));

// Serializing the "SelectedFileHolder" object
Stream writeStream = File.Open(Form1.SaveFilePath, FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();

bformatter.Serialize(writeStream, holder);
writeStream.Close();

// Deserializing the stored "SelectedFileHolder" object
Stream readStream = File.Open(Form1.SaveFilePath, FileMode.Open);
bformatter = new BinaryFormatter();

SelectedFileHolder newHolder = (SelectedFileHolder)bformatter.Deserialize(readStream);
writeStream.Close();

// Checking the data :)
MessageBox.Show(string.Format("{0} : {1}", newHolder.fileList[0].fileName, newHolder.fileList[0].fileData.Length));


Since you said you know I will not be explaining about "Serializing". In case you need help with that refer to this article[^]. It got everything you need to know to achieve what you need and my solution is based on that article too.

Hope this helps :) Regards
 
Share this answer
 
v3
I assume that you are asking how to compress multiple files into one output stream. If you are trying to compress from class files, all you need to do is create a super class that contains the classes you want to serialize out, and then serialize that class out (as long as the other classes are serializable, it's job done).

If you are trying to pack multiple files together that aren't part of a program, you could read them into a list of byte arrays and then serialize that. Without knowing much more about what you are trying to do, this is the best I can do.

As a hint, the more information you put into a question, the more detailed an answer you will get. You aren't limited in the length of the question that you can ask.
 
Share this answer
 
Comments
yesotaso 2-May-11 17:46pm    
Question:?
Answer:!
Audience:hmm :)
CodeHawkz 3-May-11 2:55am    
lol @ yesotaso

I remember feeling like that in my "threads and concurrency" classes :D
I'd say, keep it simple. Assuming you do not need any processing on files in subject, decide a pattern like

The number of files (Int32)
List of <File Size Int32 - File name (252 bytes for each for simplicty)>
List of <Raw Data>

For instance:

2 Files
36514(File size)  "testfile.txt" + 240 "\0" (filename)
123475(File size) "testfile2.txt" + 239 "\0" (filename)
[your testfile.txt as byte array]
[your testfile2.txt as byte array]


The basic things to deal with are:
C#
// To write
FileStream fileToWrite = File.Open("target.dat",FileMode.Create);
BinaryWriter bw = new BinaryWriter( fileToWrite );
// look BinaryWriter reference for how to write stuff
//And to read
FileStream fileToRead = File.OpenRead("target.dat");
BinaryReader bw = new BinaryReader( fileToRead );
// look BinaryReaderreference for how to read stuff

If you want to get involved with more advanced classes, fine the more you deal with the more you learn but do not choke on information :)
 
Share this answer
 
Comments
SeniorEng 19-Dec-11 9:29am    
when i open the packed file how to delete it

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900