C# 如何保存多个文件在一个文件中保存

C# 如何保存多个文件在一个文件中保存,c#,C#,我的朋友寄给我一份文件。他在一个文件中保存了多个gif文件,他给了我如下列表 file1 - StartFrom - 1 and length 18493, file2 - StartFrom - 132089 and length 824, file3 - StartFrom - 18494 and length 2476 etc.. 我不知道他是怎么把所有的gif文件放进一个文件的。我需要从这个文件中提取所有gif图像 有人能帮我用vb.net或C#编写代码吗。我在下面写了一段代码: pr

我的朋友寄给我一份文件。他在一个文件中保存了多个gif文件,他给了我如下列表

file1 - StartFrom - 1 and length 18493,
file2 - StartFrom - 132089 and length 824,
file3 - StartFrom - 18494 and length 2476 etc..
我不知道他是怎么把所有的gif文件放进一个文件的。我需要从这个文件中提取所有gif图像

有人能帮我用vb.net或C#编写代码吗。我在下面写了一段代码:

private void button1_Click(object sender, EventArgs e)
{

    byte[] buffer = new byte[18493];


    string destPath = Application.StartupPath + "\\mm.gif";
    string sourcePath = Application.StartupPath + "\\Data.qdd";

    var destStream = new FileStream(destPath, FileMode.Create);

    int read;
    var sourceStream = new FileStream(sourcePath, FileMode.Open);
    while ((read = sourceStream.Read(buffer, 1, 18493)) != 0)
          destStream.Write(buffer, 0, read);

}
但有一个错误,错误是:

偏移量和长度超出了数组的界限,或者计数大于从索引到源集合末尾的元素数


编辑编辑的解决方案

错误就在这里

read = sourceStream.Read(buffer, 1, 18493)
创建一个长度为18493的缓冲区字节数组变量,因此它有18493个元素。 数组中的位置从0到18492。 Read函数尝试从位置1写入18943字节,因此最后一个字节将写入缓冲区[18943],超出数组的限制。 尝试将读取更改为

read = sourceStream.Read(buffer, 0, 18493)
编辑整个问题的2个解决方案

要解决这个问题,而不仅仅是错误,您应该分配三个不同的缓冲区并释放不同的文件。(您可以只使用一个缓冲区,每次清洗一次,但如果使用三个缓冲区,则更容易理解)
您不能用一段时间来阅读,因为这样您将进入文件的末尾
只需读取所需长度的文件,然后移动到下一个文件

private void button1_Click(object sender, EventArgs e)
{

    byte[] buffer1 = new byte[18493];
    byte[] buffer2 = new byte[824];
    byte[] buffer3 = new byte[2476];


    string destPath1 = Application.StartupPath + "\\mm1.gif";
    string destPath2 = Application.StartupPath + "\\mm2.gif";
    string destPath3 = Application.StartupPath + "\\mm3.gif";
    string sourcePath = Application.StartupPath + "\\Data.qdd";

    var destStream1 = new FileStream(destPath1, FileMode.Create);
    var destStream2 = new FileStream(destPath2, FileMode.Create);
    var destStream3 = new FileStream(destPath3, FileMode.Create);

    int read;
    var sourceStream = new FileStream(sourcePath, FileMode.Open);
    if ((read = sourceStream.Read(buffer1, 0, 18493)) != 0)
          destStream1.Write(buffer1, 0, read);
    //file three is the next in the stream
    if ((read = sourceStream.Read(buffer3, 0, 2476)) != 0)
          destStream3.Write(buffer3, 0, read);
    //there some unused space, move to the start of the second gif file
    sourceStream.Seek(132089, SeekOrigin.Begin);
    if ((read = sourceStream.Read(buffer2, 0, 824)) != 0)
          destStream2.Write(buffer2, 0, read);

}
//存储文件信息的结构
结构文件
{
公共字符串文件名{get;set;}
公共int起始位置{get;set;}
公共整数长度{get;set;}
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
//首先,我们需要从字符串中获取有关文件的信息。
字符串描述=@“file1-StartFrom-1,长度18493,
文件2-从-132089开始,长度为824,
文件3-从18494开始,长度为2476”;
字符串模式=@“(\w+)-StartFrom-(\d+)和长度(\d+);
var matches=Regex.matches(描述、模式);
列表文件=新列表();
foreach(匹配中的匹配)
{
GifFile GifFile=新的GifFile
{
FileName=match.Groups[1]。值,
startPosition=int.Parse(match.Groups[2].Value),
Length=int.Parse(match.Groups[3].Value)
};
文件。添加(gifFile);
}
字符串sourcePath=Path.Combine(Application.StartupPath,“Data.qdd”);
使用(var sourceStream=newfilestream(sourcePath,FileMode.Open))
{
//对于文件列表中的每个文件,我们获取数据并创建gif文件。
foreach(文件中的GifFile)
{
字符串outputPath=Path.Combine(Application.StartupPath,file.FileName+“.gif”)
使用(FileStream destStream=newfilestream(outputPath,FileMode.Create))
{
byte[]buffer=新字节[file.Length];
sourceStream.Position=file.startPosition;
int readLength=sourceStream.Read(缓冲区,0,file.Length);
if(readLength==file.Length)
{
destStream.Write(缓冲区,0,文件长度);
}
}
}
}
}

此代码的问题可能是流从0开始计数。因此,你可以将
sourceStream.Position
设置为
file.startPosition-1

猛击你的朋友的头,让他像普通人一样给你寄一份ZIP档案?@ipavlic
家庭作业
标签死于火灾,试着根据问题本身的优点来判断问题,而不是猜测上下文。错误发生在哪一行?传递给该行调用的方法的参数值是多少?基本上,启动调试器并首先尝试收集其中的任何信息。这很可能是因为文件的大小不是缓冲区大小的倍数。无论如何,我猜调用应该是
sourceStream.Read(buffer,018943)
-您没有指向缓冲区的开头,但是第二项。如果
Read()
返回的文件长度小于
file.Length
字节,则此项将中断。(对于这么小的文件可能不太可能,但它仍然会忽略
Stream.Read()
)的约定,如果输入文件不存在,它也会下降。一方面,我们应该在示例中使用正确的错误处理。另一方面,它会使例子更大,更难阅读。实际上,我不知道什么更好,但我知道什么更简单:)这不是错误处理。这并不是像预期的那样使用
Read()
Read()
返回的字节数小于最大字节数不是错误,这是一种预期的情况,应该在任何正确的代码中处理。如果出现这种情况(很可能是从网络中读取),代码将以静默方式失败并执行错误的操作。这不是“省略错误处理”,这是一个bug,简单明了。谢谢你的帮助。我不需要什么帮助。我的软件运行良好。但这幅图中的问题并没有显现出来。我认为主源文件(Data.qdd)不是图像格式。我从主文件中提取,但我想我需要以gif图像格式保存文件。如何转换gif图像格式。@dralialadin在回答的评论中不要纠缠于进一步的问题。发布一个新问题,包括示例代码和所有内容。也就是说,如果您不知道原始文件的格式,就无法神奇地将其转换为。gif@dralialadin是的,米利穆斯是对的。你应该提出一个新问题。我也不知道如何把它转换成.gif,对不起。
//struct to store information about file
struct GifFile
{
    public string FileName { get; set; }
    public int startPosition { get; set; }
    public int Length { get; set; }
}

private void button1_Click(object sender, EventArgs e)
{
    //first we need to get information about files from string.
    String description = @"file1 - StartFrom - 1 and length 18493,
        file2 - StartFrom - 132089 and length 824,
        file3 - StartFrom - 18494 and length 2476";
    String pattern = @"(\w+) - StartFrom - (\d+) and length (\d+)";
    var matches = Regex.Matches(description, pattern);
    List<GifFile> files = new List<GifFile>();
    foreach (Match match in matches)
    {
        GifFile gifFile = new GifFile
        {
            FileName = match.Groups[1].Value,
            startPosition = int.Parse(match.Groups[2].Value),
            Length = int.Parse(match.Groups[3].Value)
        };
        files.Add(gifFile);
    }

    string sourcePath = Path.Combine(Application.StartupPath, "Data.qdd");
    using (var sourceStream = new FileStream(sourcePath, FileMode.Open))
    {
        // for each file in file list we take data and create gif file.
        foreach (GifFile file in files)
        {
            String outputPath = Path.Combine(Application.StartupPath, file.FileName + ".gif")
            using (FileStream destStream = new FileStream(outputPath , FileMode.Create))
            {
                byte[] buffer = new byte[file.Length];

                sourceStream.Position = file.startPosition;
                int readLength = sourceStream.Read(buffer, 0, file.Length);
                if(readLength == file.Length)
                {
                    destStream.Write(buffer, 0, file.Length);
                }
            }
        }
    }
}