C# WinForms 文件分割工具






4.53/5 (18投票s)
2003年9月26日
3分钟阅读

111943

6176
简单的文件分割/合并实用工具,演示了 FCL 和 Winforms UI 处理
引言
- 该项目是一个简单的文件分割/合并应用程序。它由一个简单的 UI 组成,该 UI 与一个简单的控制器类交互。控制器类负责协调来自 UI 的请求,启动 2 个工作类 (
FileSplitter
&FileJoiner
),并处理使用活动进度更新 UI。
该项目介绍了一些 .NET 基类中 Stream 的优秀功能。在 C++ 中需要大量代码的内容可以大大减少。它还提供了在层(UI、控制器、处理)之间绑定事件和委托的功能。
背景
我最初创建工作类是为了分割大型 MPEG 文件,以便它们可以放入 600 MB 的 CD 中。然而,我经常发现需要在互联网上使用 FTP、电子邮件等传输文件时分割文件。虽然 WinRar 等实用程序可以为您完成此操作,但最终您必须为简单任务支付软件费用。它们确实增加了 zip 功能,但是 MPEG 文件和现有的 Zip 文件已经被压缩了。所以,我只需要一个分割/合并工具,这就是它。
使用代码
FileSplitter / File Joiner 类
这些类公开了一组简单的方法和一个名为 ProgressNotify
的事件。此事件将仅提供正在处理的任务的完成百分比。还有进一步的控制功能,用于调整内部缓冲区的大小以及文件段的大小。并非 UI 使用了该类的所有属性。它还仅使用简单的文件名机制来生成输出文件。如果输入文件名为 *Test.zip*,则段命名为 *Test.zip.0*,*Test.zip.1* 等。
FileSplitter
有一个真实的方法,它只是接受要分割的文件名并使用文件命名约定。
FileJoiner
有一堆用于合并文件的额外方法,但 UI 仅使用 1 个。
最后,FileJoiner
执行与 DOS 命令“*copy /b file1 + file2 + file3 finalfile* ”等效的操作。
控制器 (Controller)
在 UI 项目中,有一个控制器类负责接受来自 UI 的请求并使用 ThreadPool
生成工作线程。
Controller
的构造函数接受窗体和该窗体上的一个委托,该委托将处理进度更新。该窗体还有一个处理程序,该处理程序仅使用 OwnerDraw
更新状态栏内的进度条。
public Controller( Form owner, Delegate senderDelegate)
{
m_sender = owner;
m_senderDelegate = senderDelegate;
}
然后,它使用其 NotifyHandler
委托注册 FileSplitter
/FileJoiner
以接受事件。
fs.ProgressNotify += new ProgressNotifyHandler(NotifyHandler);
NotifyDelegate 进而使用以下方法异步更新 UI 中的任务进度。
private void NotifyHandler( int i ) { m_sender.BeginInvoke(
m_senderDelegate, new object[] { i } ); }
MainForm
主窗体很简单。双击“文件名”文本字段会弹出一个文件选择对话框。选择一个文件,然后选择兆字节或千字节,然后单击“*分割文件*”。
合并文件时,如果选择的文件不以“0”结尾(表示它是序列中的第一个),您将收到异常。此外,它只够智能地按数字顺序合并文件。如果连接时缺少文件,它将继续而不失败 - 尽管这可能不是正确的行为,但对 FileJoiner
的简单更改可以处理该问题。
另一个有趣的事情是在面板内的状态栏上显示进度条。
这是通过以下方式完成的 - 首先将进度条添加到控件集合中
progressBar1 = new ProgressBar();
this.Controls.Add(progressBar1); //not really sure if I need this!!!
this.statusBar.Controls.Add( this.progressBar1 );
然后,为状态栏的 OwnerDraw 事件添加一个方法并将其连接起来。
连接
this.statusBar.DrawItem +=
new System.Windows.Forms.StatusBarDrawItemEventHandler(
this.statusBar_DrawItem);
绘制的方法
private void statusBar_DrawItem(object sender,
System.Windows.Forms.StatusBarDrawItemEventArgs sbdevent)
{
if ( sbdevent.Panel == this.statusBarPanel1 )
{
this.progressBar1.Bounds = sbdevent.Bounds;
}
}
历史
- 2003-09-25 第一个版本