C#跟踪写入的字节数

时间:2016-10-13 12:55:31

标签: c# wpf file byte

我正在研究编写数据,我用过:

System.IO.File.WriteAllBytes(path, GetBytes());

这对我有用但后来我想获得写入字节的进度,所以我可以添加一个进度条。我发现我的方法无法连接到进度条,所以我决定使用它:

using (BinaryWriter writer = new BinaryWriter(System.IO.File.Open(path, FileMode.Create))) {
            byte[] nextBytes = GetBytes(); // your logic to get what to write;
            writer.Write(nextBytes);
        }

这会成功写入我的文件,但经过大量搜索(可能还不够)后,我似乎无法找到如何跟踪写入的字节数,直到完成为止。也许我使用了错误的方法,如果有人能帮助我,那就太棒了! (我使用WPF)

提前致谢,

更新

在项目之上我delcare BackgroundWorker()

    BackgroundWorker bw;

然后,当我开始下载时,我认为:

bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

            bw.RunWorkerAsync(data);

我的工作方法:

        private void bw_DoWork (object sender, DoWorkEventArgs e) {
        downloadData data = (downloadData) e.Argument;
        _source = data.DownloadLocation + @"\";

        sem.WaitOne();

        //enters
        updateStatusBar("- Downloading -", data, 0);
        Video vid = youtube.GetVideo(data.Url);
        byte[] bytes = vid.GetBytes();

        using (var writer = new BinaryWriter(System.IO.File.Open(_source + vid.FullName, FileMode.Create))) {

            // do your read logic here and read into bytes

            var bytesLeft = bytes.Length;
            var bytesWritten = 0;
            while (bytesLeft > 0) {
                int chunk = Math.Min(64, bytesLeft);

                writer.Write(bytes, bytesWritten, chunk);
                bytesWritten += chunk;
                bytesLeft -= chunk;

                // calculate progress bar status
                bw.ReportProgress(bytesWritten * 100 / bytes.Length, data);
            }
        }
        // Leaves
        updateStatusBar("- Done -", data, 100);

        sem.Release();
    }

我的Progresschanged方法:

    private void bw_ProgressChanged (object sender, ProgressChangedEventArgs e) {
        YoutubeData data = (YoutubeData) e.UserState;
        updateStatusBar("Downloading: " + e.ProgressPercentage, data, e.ProgressPercentage);
    }

更新状态栏的方法:

        private void updateStatusBar(string txt, downloadData data, int progress) {
        _downloadData.Remove(data);
        data.ProgressText = txt;
        data.Status = progress;
        _downloadData.Add(data);

        Dispatcher.Invoke(new Action(() => {
            lv_DownloadData.ItemsSource = null;
            lv_DownloadData.ItemsSource = _youtubeData;
        }));
    }

但现在它冻结了我的WPF。

1 个答案:

答案 0 :(得分:3)

以块的形式写入字节并使用BackgroundWorker

    using(var writer = new BinaryWriter(System.IO.File.Open(path, FileMode.Create)))) {

       // do your read logic here and read into bytes

        var bytesLeft = bytes.Length;
        var bytesWritten = 0;
        while(bytesLeft > 0) {
            int chunk = Math.Min(64, bytesLeft);
            writer.WriteBytes(array, bytesWritten, chunk);
            bytesWritten += chunk;
            bytesLeft -= chunk;

            // calculate progress bar status
            backgroundWorker.ReportProgress(bytesWritten * 100 / array.Length);
        }
    }

<强>更新

好的,这纯粹是未经测试的......但请留下我们...... 每个BinaryWriter都会在BackgroundWorker

上完成工作

所以你设置了后台工作者

BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

然后您需要使用BackgroundWorker

在某个地方启动bw.RunWorkerAsync()
void bw_DoWork(object sender, DoWorkEventArgs e)
{
    // Do your task here

     // report its progress
    bw.ReportProgress(..); 
}

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // update your progress bar here

}