-3

我正在开发一个项目,其概念基本上是充当文件容器并将文件收集到一个容器中。到目前为止,我创建了一个“容器”文件,它在开头分配了 2mb 用于索引文件。这部分是一段简单的 XML,我在其中存储文件名、偏移量、文件大小等信息。其余部分是在分配 2mb 后添加到分叉容器中的文件。

目前,如果我创建一个容器并添加文件,它就像一个魅力。问题是,如果我想添加更多内容,XmlDocument 将在保存后删除其余内容。

我的问题是:我应该使用 XML 来做索引,如果是的话,如何在不丢失的情况下更新它,或者我应该以不同的方式进行?

谢谢你的建议!

4

2 回答 2

5

我认为您应该在重新发明轮子之前查看 SharpZipLib。

对于您的问题的答案,您应该首先将 xml 保存到内存流中,然后将该流复制到您的文件中。(这样你就会知道你是否超过 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);
    }
}

但我认为更好的方法是在文件之前创建一个标题:

  File 1                                    File 2
+--------------------------+--------------+--------------------------+--------------+
| NextOffset|Filename|Size | FileData     | NextOffset|Filename|Size | FileData     |
+--------------------------+--------------+--------------------------+--------------+

这样您就可以轻松添加/删除文件。


另一个想法可能是在文件末尾写入 fileinfolist。喜欢:

+----------+----------+----------+---------------+------------------------------+
| Filedata | Filedata | Filedata | FileInfoTable | FileInfoTableOffset (4bytes) |
+----------+----------+----------+---------------+------------------------------+

FileInfoTableOffset 将指向 FileInfoTable 的起始地址。如果要读取文件,只需将整个 FileInfoTable 放入内存中,准备好后,将其写回。

于 2013-09-18T07:17:28.930 回答
1

我尝试了另一种方式。

我创建了一个这样的可序列化类:

[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;
}

它目前就像一个魅力:)

于 2013-09-18T15:33:35.327 回答