-3

友達がファイルを送ってくれます。彼は複数のgifファイルを1つのファイルに保存し、次のようなリストをくれます

file1 - StartFrom - 1 and length 18493,
file2 - StartFrom - 132089 and length 824,
file3 - StartFrom - 18494 and length 2476 etc..

彼がすべての gif ファイルを 1 つのファイルにまとめた方法がわかりません。このファイルからすべての 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
//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 に答える
0

EDIT 編集されたソリューション

エラーはここにあります

read = sourceStream.Read(buffer, 1, 18493)

長さ 18493 のバッファーバイト配列変数を作成すると、18493 の要素が含まれます。配列内の位置は 0 から 18492 です。Read関数は位置 1 から 18943 バイトを書き込もうとするため、最後のバイトがバッファ [18943] に書き込まれ、配列の制限を超えます。読み取りをに変更してみてください

read = sourceStream.Read(buffer, 0, 18493)

編集2問題全体の解決策

エラーだけでなく問題を解決するには、3 つの異なるバッファーを割り当て、別のファイルに空きを書き込む必要があります。(バッファを 1 つだけ使用して毎回消去することもできますが、3 つ使用すると理解しやすくなります)
ファイルの末尾に移動するため、読み取りに while を使用することはできません!
必要な長さのファイルを読み取ってから、次のファイルに移動します。

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 に答える