Segmented C# file downloader
Asked Answered
M

1

7

Have been trying to write a program in C# that downloads a file using multiple segments at once like most download managers, and I've run into the issue that the files downloaded are corrupted. E.g., I download a video and it plays for 2 seconds then WMP says it's unplayable.

I hexedited the downloaded file and it appears there are sections of zerobytes scattered throughout the file, anyone have any ideas why? VS reports no errors.

getPart() is called for each segment in a separate thread.

public long start;
public long end;
public int thread;
public Form1 handle;
public myFile handler;
public void getPart()
{
    log("getting part " + start.ToString() + "," + end.ToString());
    HttpWebRequest part = (HttpWebRequest)WebRequest.Create(handler.url);
    part.AddRange((int)start,(int) end);
    HttpWebResponse pr = (HttpWebResponse)part.GetResponse();
    Stream rstream = pr.GetResponseStream();
    log("Beginning part " + start.ToString());
    int totalbytes = 0;
    byte[] buffer = new byte[256];
    int x = rstream.Read(buffer, 0, 256);
    while (x > 0)
    {
        handler.writeFile(buffer, (int)(totalbytes + start), x);
        totalbytes += x;
        x = rstream.Read(buffer, 0, 256);
    }
    log(start.ToString() + "-byte start part done...");
    rstream.Close();
    pr.Close();
    handler.partDone(thread);
    return;
}

public void writeFile(byte[] buffer, int start, int size)
{
    mFileStream.Seek(start, SeekOrigin.Begin);
    mFileStream.Write(buffer, 0, size);
    return;
}
Multitudinous answered 2/12, 2009 at 7:52 Comment(0)
M
12

Well I've figured it out, just thought I'd leave an answer for anyone having similar issues. A lock is required around the file writing stream.

public void writeFile(byte[] buffer, int start, int size)
    {
        mFileStream.Seek(start, SeekOrigin.Begin);
        mFileStream.Write(buffer, 0, size);
        return;
    }

becomes

public void writeFile(byte[] buffer, int start, int size)
    {
        lock (mFileStream)
        {
        mFileStream.Seek(start, SeekOrigin.Begin);
        mFileStream.Write(buffer, 0, size);
        return;
        }
    }
Multitudinous answered 2/12, 2009 at 23:15 Comment(2)
thank you, just wondering, the downloading is not in parallel, right?Lepidosiren
I guess not, start and end is outside the method. with this you can play the video while downloading.Trapeze

© 2022 - 2024 — McMap. All rights reserved.