我编写了以下方法,使用二进制模式将文件存档到一个文件中:
// 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;
}
}
我使用ReadFileData读取文件数据,该方法在上面的方法中返回一串数据。 (StreamReader)接下来我提取我的档案。一切都做得很好,但是存储在提取方法中的数据不能为我提供正确的数据,因此提取的文件没有正确的数据来显示其原始功能。
提取方法:
// 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;
}
}
结构:
struct FileTemplate
{
public string Name, Path, Data;
}
感谢。
答案 0 :(得分:1)
如果您的Data
可以是二进制数据,那么您不应该将它们放在string
中。它们应该是byte[]
。
当您像使用ASCII编码一样编写字符串并尝试编写二进制数据时,许多字节(视为Unicode字符)无法编码,因此您最终会损坏数据。
故事的故事:永远不要将二进制数据视为文本。
答案 1 :(得分:1)
考虑使用字节数组进行写入并保护数据。
字节数组(写)
Byte[] bytes = File.ReadAllBytes(..);
// Write it into your stream
myStream.Write(bytes.Count);
myStream.Write(bytes, 0, bytes.Count);
字节数组(读取)
Int32 byteCount = myStream.ReadInt32();
Byte[] bytes = new Byte[byteCount];
myStream.Read(bytes, 0, byteCount);
答案 2 :(得分:0)
图标示例清晰明了;您正在使用基于字符串的API来处理非字符串的数据(图标不是基于字符串的)。此外,您使用的是ASCII,因此只有0-127范围内的字符才是正确的。基本上,你不能这样做。您需要使用二进制方法处理二进制数据(可能使用Stream API)。
其他选择: