Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#将多个文件收集到一个文件中_C#_Xml_File - Fatal编程技术网

C#将多个文件收集到一个文件中

C#将多个文件收集到一个文件中,c#,xml,file,C#,Xml,File,我正在从事一个项目,其概念基本上是像一个文件容器一样,将文件收集到一个容器中。 到目前为止,我创建了一个“容器”文件,在开始时为索引文件分配了2mb。这部分是一个简单的XML,我在其中存储文件名、偏移量、文件大小等信息。其余的是在分配2mb后添加到分叉容器中的文件 目前,如果我创建一个容器并添加文件,它就像一个符咒。问题是,如果我想添加更多内容,XmlDocument将在保存后删除其余内容 我的问题是:我应该使用XML进行索引吗?如果是的话,如何在不丢失的情况下更新它,或者我应该以不同的方式进行

我正在从事一个项目,其概念基本上是像一个文件容器一样,将文件收集到一个容器中。 到目前为止,我创建了一个“容器”文件,在开始时为索引文件分配了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;
}