Reputation: 2382
I wrote the below method to archive files into one file using binary mode:
// Compile archive
public void CompileArchive(string FilePath, ListView FilesList, Label Status, ProgressBar Progress)
{
FileTemplate TempFile = new FileTemplate();
if (FilesList.Items.Count > 0)
{
BinaryWriter Writer = new BinaryWriter(File.Open(FilePath, FileMode.Create), System.Text.Encoding.ASCII);
Progress.Maximum = FilesList.Items.Count - 1;
Writer.Write((long)FilesList.Items.Count);
for (int i = 0; i <= FilesList.Items.Count - 1; i++)
{
TempFile.Name = FilesList.Items[i].SubItems[1].Text;
TempFile.Path = "%ARCHIVE%";
TempFile.Data = this.ReadFileData(FilesList.Items[i].SubItems[2].Text + "\\" + TempFile.Name);
Writer.Write(TempFile.Name);
Writer.Write(TempFile.Path);
Writer.Write(TempFile.Data);
Status.Text = "Status: Writing '" + TempFile.Name + "'";
Progress.Value = i;
}
Writer.Close();
Status.Text = "Status: None";
Progress.Value = 0;
}
}
I read files data using ReadFileData which is in the above method method which return a string of data. (StreamReader) Next up I extract my archive. Everything is done great but the data which will being stored in the extraction method doesn't give me a right data so the extracted files have not right data to show their original functionality.
Extract method:
// Extract archive
public void ExtractArchive(string ArchivePath, string ExtractPath, ListView FilesList, Label Status, ProgressBar Progress)
{
FileTemplate TempFile = new FileTemplate();
BinaryReader Reader = new BinaryReader(File.Open(ArchivePath, FileMode.Open), System.Text.Encoding.ASCII);
long Count = Reader.ReadInt64();
if (Count > 0)
{
Progress.Maximum = (int)Count - 1;
FilesList.Items.Clear();
for (int i = 0; i <= Count - 1; i++)
{
TempFile.Name = Reader.ReadString();
TempFile.Path = Reader.ReadString();
TempFile.Data = Reader.ReadString();
Status.Text = "Status: Reading '" + TempFile.Name + "'";
Progress.Value = i;
if (!Directory.Exists(ExtractPath))
{
Directory.CreateDirectory(ExtractPath);
}
BinaryWriter Writer = new BinaryWriter(File.Open(ExtractPath + "\\" + TempFile.Name, FileMode.Create), System.Text.Encoding.ASCII);
Writer.Write(TempFile.Data);
Writer.Close();
string[] ItemArr = new string[] { i.ToString(), TempFile.Name, TempFile.Path };
ListViewItem ListItem = new ListViewItem(ItemArr);
FilesList.Items.Add(ListItem);
}
Reader.Close();
Status.Text = "Status: None";
Progress.Value = 0;
}
}
The structure:
struct FileTemplate
{
public string Name, Path, Data;
}
Thanks.
Upvotes: 5
Views: 7902
Reputation: 6281
Consider using byte arrays for write and safe the data.
Byte array( write )
Byte[] bytes = File.ReadAllBytes(..);
// Write it into your stream
myStream.Write(bytes.Count);
myStream.Write(bytes, 0, bytes.Count);
Byte array ( read )
Int32 byteCount = myStream.ReadInt32();
Byte[] bytes = new Byte[byteCount];
myStream.Read(bytes, 0, byteCount);
Upvotes: 2
Reputation: 244757
If your Data
can be binary data, then you shouldn't have them in a string
. They should be a byte[]
.
When you write a string using the ASCII encoding like you do, and try to write binary data, many of the bytes (treated as Unicode characters) can't be encoded and so you end up with damaged data.
Morale of the story: never treat binary data as text.
Upvotes: 0
Reputation: 1062492
The example of an icon makes it clear; you are using string-based APIs to handle data that isn't strings (icons are not string-based). More, you are usig ASCII, so only characters in the 0-127 range would ever be correct. Basically, you can't do that. You need to handle binary data using binary methods (perhaps using the Stream API).
Other options:
Upvotes: 0