c#根据文件大小显示文件复制进度条实例
初学者,照着书上的抄袭制作,但已经理解了里面的意思和应用,并且进行了稍微改善和异常捕捉。这里记录下,以防以后用到这方面的知识点。
窗体设计:
code:
using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows.forms;
using system.io;
using system.threading;
namespace copyprogress015
{
public partial class form1 : form
{
public form1()
{
initializecomponent();
}
private thread thdcopyfile; //创建一个线程
private string str = ""; //用来记录源文件的名字
filestream formeropenstream; //实例化源文件filestream类
filestream tofileopenstream; //实例化目标文件filestream类
#region //复制文件 函数
/// <summary>
/// 复制文件
/// </summary>
/// <param name="formerfile">源文件路径</param>
/// <param name="tofile">目的文件路径</param>
/// <param name="transize">传输大小</param>
/// <param name="progressbar1">progressbar控件</param>
public void copyfile(string formerfile, string tofile, int transize, progressbar progressbar1)
{
progressbar1.value = 0;//设置进度条的当前位置为0
progressbar1.minimum = 0; //设置进度条的最小值为0
try
{
formeropenstream = new filestream(formerfile, filemode.open, fileaccess.read);//以只读方式打开源文件
}
catch (ioexception ex)
{
messagebox.show(ex.message);
return;
}
try
{
filestream filetocreate = new filestream(tofile, filemode.create); //创建目的文件,如果已存在将被覆盖
filetocreate.close();//关闭所有filetocreate的资源
filetocreate.dispose();//释放所有filetocreate的资源
}
catch(ioexception ex)
{
messagebox.show(ex.message);
return;
}
tofileopenstream = new filestream(tofile, filemode.append, fileaccess.write);//以写方式打开目的文件
int max = convert.toint32(math.ceiling((double)formeropenstream.length / (double)transize));//根据一次传输的大小,计算最大传输个数. math.ceiling 方法 (double),返回大于或等于指定的双精度浮点数的最小整数值。
progressbar1.maximum = max;//设置进度条的最大值
int filesize; //每次要拷贝的文件的大小
if (transize < formeropenstream.length) //如果分段拷贝,即每次拷贝内容小于文件总长度
{
byte[] buffer = new byte[transize]; //根据传输的大小,定义一个字节数组,用来存储传输的字节
int copied = 0;//记录传输的大小
int tem_n = 1;//设置进度栏中进度的增加个数
while (copied <= ((int)formeropenstream.length - transize))
{
filesize = formeropenstream.read(buffer, 0, transize);//从0开始读到buffer字节数组中,每次最大读transize
formeropenstream.flush(); //清空缓存
tofileopenstream.write(buffer, 0, transize); //向目的文件写入字节
tofileopenstream.flush();//清空缓存
tofileopenstream.position = formeropenstream.position; //是源文件的目的文件流的位置相同
copied += filesize; //记录已经拷贝的大小
progressbar1.value = progressbar1.value + tem_n; //增加进度栏的进度块
}
int leftsize = (int)formeropenstream.length - copied; //获取剩余文件的大小
filesize = formeropenstream.read(buffer, 0, leftsize); //读取剩余的字节
formeropenstream.flush();
tofileopenstream.write(buffer, 0, leftsize); //写入剩余的部分
tofileopenstream.flush();
}
else //如果整体拷贝,即每次拷贝内容大于文件总长度
{
byte[] buffer = new byte[formeropenstream.length];
formeropenstream.read(buffer, 0, (int)formeropenstream.length);
formeropenstream.flush();
tofileopenstream.write(buffer, 0, (int)formeropenstream.length);
tofileopenstream.flush();
}
formeropenstream.close();
tofileopenstream.close();
if (messagebox.show("copy finished") == dialogresult.ok)
{
progressbar1.value = 0;
txtoriginalfile.clear();
txtcopyfile.clear();
str = "";
}
}
#endregion
public delegate void copyfile_delegate(); //定义委托/托管线程
/// <summary>
/// 在线程上执行委托(设置托管线程函数)
/// </summary>
public void setcopyfile()
{
//this.invoke(new copyfile_delegate(runcopyfile)); //对指定的线程进行托管
//下面两行代码等同上面一行代码
copyfile_delegate copyfile_delegate = new copyfile_delegate(runcopyfile); //创建delegate对象
this.invoke(copyfile_delegate); //调用delegate
}
/// <summary>
/// 设置线程,运行copy文件,它与代理copyfile_delegate应具有相同的参数和返回类型
/// </summary>
public void runcopyfile()
{
copyfile(txtoriginalfile.text, txtcopyfile.text + "\\" + str, 1024, progressbar1); //复制文件
thread.sleep(0); //避免假死
thdcopyfile.abort(); //关闭线程
}
private void btnoriginalfile_click(object sender, eventargs e)
{
if (openfiledialog1.showdialog() == dialogresult.ok) //打开文件对话框
{
txtoriginalfile.text = openfiledialog1.filename; //获取源文件的路径
}
}
private void btncopyfile_click(object sender, eventargs e)
{
if (folderbrowserdialog1.showdialog() == dialogresult.ok)
{
txtcopyfile.text = folderbrowserdialog1.selectedpath;//获取目的文件的路径
}
}
private void btnbegintocopy_click(object sender, eventargs e)
{
if (txtoriginalfile.text.trim() == string.empty)
{
messagebox.show("originalfile cannot be empty!");
return;
}
else
{
str = txtoriginalfile.text;//记录源文件的路径
str = str.substring(str.lastindexof('\\') + 1, str.length - str.lastindexof('\\') - 1); //获取源文件的名称
}
if (txtcopyfile.text.trim() == string.empty)
{
messagebox.show("the copyfile path cannot be empty!");
return;
}
else
{
thdcopyfile = new thread(new threadstart(setcopyfile));
thdcopyfile.start();
}
}
/// <summary>
/// 给textbox增加tooltip
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtoriginalfile_mousehover(object sender, eventargs e)
{
tooltip tooltip = new tooltip();
if (txtoriginalfile.text.trim() != string.empty)
{
tooltip.show(txtoriginalfile.text, txtoriginalfile);
}
else
{
tooltip.hide(txtoriginalfile);
}
}
/// <summary>
/// 给textbox增加tooltip
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtcopyfile_mousehover(object sender, eventargs e)
{
tooltip tooltip = new tooltip();
if (txtcopyfile.text.trim() != string.empty)
{
tooltip.show(txtcopyfile.text, txtcopyfile);
}
else
{
tooltip.hide(txtcopyfile);
}
}
}
}
上一篇: C#引用类型和值类型的介绍与实例
推荐阅读