C#将多个文件收集到一个文件中
我正在从事一个项目,其概念基本上是像一个文件容器一样,将文件收集到一个容器中。 到目前为止,我创建了一个“容器”文件,在开始时为索引文件分配了2mb。这部分是一个简单的XML,我在其中存储文件名、偏移量、文件大小等信息。其余的是在分配2mb后添加到分叉容器中的文件 目前,如果我创建一个容器并添加文件,它就像一个符咒。问题是,如果我想添加更多内容,XmlDocument将在保存后删除其余内容 我的问题是:我应该使用XML进行索引吗?如果是的话,如何在不丢失的情况下更新它,或者我应该以不同的方式进行C#将多个文件收集到一个文件中,c#,xml,file,C#,Xml,File,我正在从事一个项目,其概念基本上是像一个文件容器一样,将文件收集到一个容器中。 到目前为止,我创建了一个“容器”文件,在开始时为索引文件分配了2mb。这部分是一个简单的XML,我在其中存储文件名、偏移量、文件大小等信息。其余的是在分配2mb后添加到分叉容器中的文件 目前,如果我创建一个容器并添加文件,它就像一个符咒。问题是,如果我想添加更多内容,XmlDocument将在保存后删除其余内容 我的问题是:我应该使用XML进行索引吗?如果是的话,如何在不丢失的情况下更新它,或者我应该以不同的方式进行
谢谢你的建议 我认为在改造车轮之前,你应该先看看SharpZipLib 为了回答您的问题,您应该首先将xml保存到memorystream,然后将该流复制到您的文件中。(这样,如果超过2mb大小,您就知道了) 我不建议使用xml,也不建议使用2mb,因为初学者的大小差不多。 我会使用像二进制读写器这样的东西 这只是一个例子:
public class FileData
{
public string Filename { get; set; }
public int Size {get; set; }
public int ContainerFileOffset { get; set; }
}
List<FileData> files = new List<FileData>();
using(Stream stream = new ...Stream(...))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(files.Count);
foreach(FileData fd in files)
{
writer.Write(Filename);
writer.Write(Size);
writer.Write(ContainerFileOffset);
}
}
这样,您可以轻松地添加/删除文件
另一个想法是在文件末尾编写fileinfolist。比如:
+----------+----------+----------+---------------+------------------------------+
| Filedata | Filedata | Filedata | FileInfoTable | FileInfoTableOffset (4bytes) |
+----------+----------+----------+---------------+------------------------------+
FileInfoTableOffset将指向FileInfoTable的起始地址。如果您想读取该文件,只需将整个FileInfoTable放入内存,准备好后,将其写回。我尝试了另一种方法 我创建了一个可序列化的类,如下所示:
[Serializable]
public class FileEntry
{
public string Name { get; set; }
public byte[] Content { get; set; }
}
在类处理文件中:
public void AddFiles(string[] Files)
{
int index = _files.Count;
foreach (string file in Files)
{
{
_files.Add(new FileEntry());
_files[index].Name = Path.GetFileNameWithoutExtension(file);
_files[index].Content = File.ReadAllBytes(file);
index++;
}
byte[] bytes = null;
BinaryFormatter serializer = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream())
{
serializer.Serialize(memoryStream, _files);
bytes = memoryStream.ToArray();
}
File.WriteAllBytes(_filePath, bytes);
}
而且:
public List<FileEntry> GetFiles()
{
byte[] bytes = File.ReadAllBytes(_filePath);
if (bytes.Length > 0)
{
BinaryFormatter serializer = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream(bytes))
_files = serializer.Deserialize(memoryStream) as List<FileEntry>;
}
return _files;
}
公共列表GetFiles()
{
byte[]bytes=File.ReadAllBytes(_filePath);
如果(bytes.Length>0)
{
BinaryFormatter序列化程序=新的BinaryFormatter();
使用(MemoryStream MemoryStream=新的MemoryStream(字节))
_files=序列化程序。反序列化(memoryStream)为列表;
}
返回_文件;
}
它目前的工作方式就像一个符咒:)XmlDocument从何而来?看起来像一个XY问题当你添加一个新的时,你确定你在引用你自己的索引并且知道以“最后一个索引+最后一个文档长度”开始写作吗?你的问题我不清楚。您的核心问题似乎是,在开始编辑XML索引部分后,文件的其余部分(?)会被删除?请添加一些代码,说明您是如何做到这一点的。首先,感谢您的回答和建议。我目前正在使用FileStream with File.ReadAllBytes()将文件复制到容器中,但我将尝试使用BinaryStream(我是这种流的新手),在每个文件开始出现之前添加一个头,特别是我不需要为全局头分配空间。我想我会为nextofset、Filename、Size分配几个字节,这样我就可以读取并访问数据了。使用BinaryStream会更快?我认为使用BinaryWriter来编写文件信息会比使用xml更快。我将更新我的答案以获得另一个想法。嗨,Jeroen,结尾的FileInfoTable和offset看起来是个好主意。你认为你的方法会比我上面贴的更有效吗?今天早上我使用BinaryWriter时有点出错,但也许我会再试一次。无论如何,谢谢你的建议!
public List<FileEntry> GetFiles()
{
byte[] bytes = File.ReadAllBytes(_filePath);
if (bytes.Length > 0)
{
BinaryFormatter serializer = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream(bytes))
_files = serializer.Deserialize(memoryStream) as List<FileEntry>;
}
return _files;
}