-3

我的朋友给我发了一个文件。他将多个 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);

}

但是有错误显示是:

数组的偏移量和长度超出范围或计数大于从索引到源集合末尾的元素数。

4

2 回答 2

0

编辑编辑的解决方案

错误就在这里

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);

}
于 2012-11-12T14:16:20.657 回答
0
//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);
                }
            }
        }
    }
}

此代码的问题可能是流从 0 开始计数。因此您可以设置sourceStream.Positionfile.startPosition - 1

于 2012-11-12T14:44:39.633 回答