[译]J-AXE:C#中的文件分割器
By robot-v1.0
本文链接 https://www.kyfws.com/applications/jaxe-a-file-splitter-in-csharp-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 10 分钟阅读 - 4935 个词 阅读量 0[译]J-AXE:C#中的文件分割器
原文地址:https://www.codeproject.com/Articles/223791/JAXE-A-File-Splitter-in-Csharp
原文作者:jawed.ace
译文由本站 robot-v1.0 翻译
前言
J-AXE file splitter is a Windows application developed using C# .NET to split file into time interval based on size and total files after splits.
J-AXE文件拆分器是Windows应用程序,使用C#.NET开发,可根据文件大小和拆分后的文件总数将文件拆分为时间间隔.
- 下载JAXE-DLL-103.36 KB(Download JAXE-DLL - 103.36 KB)
- 下载JAXEFileSplitter源代码-36.05 KB(Download JAXEFileSplitter source code - 36.05 KB)
- 下载JAXEFileSplitter设置-473.21 KB(Download JAXEFileSplitter setup - 473.21 KB)
- 下载JAXE_DLL源代码-109.56 KB(Download JAXE_DLL source code - 109.56 KB)
介绍(Introduction)
J-AXE文件分割器(J-AXE file splitter)是Windows开发的应用程序,使用C#.NET根据大小和拆分后的文件总数将文件拆分为时间间隔.我不会忽略这是某种新应用的事实.已经有许多开源项目可以实现相同的目的.然后的问题是,为什么我要花很多时间来开发该应用程序:请允许我解释一下这个问题:无论应用程序是开放的还是付费的,您都不会获得基于时间间隔或持续时间来拆分文件的选项.但是在这里,您将获得此功能以及具有新风格的其他功能.重点是我想使用C#进行开发. NET,通过开发这种应用程序,我将有机会学习新知识,甚至可以将自己的业余时间用于生产成果.所以我做了这个,这是这个的UI(is a Windows application developed using C# .NET to split file into time interval based on size and total files after splits. I would not ignore the fact that this is some kind of new application. Already there are so many open source projects available to achieve the same purpose. Then the question is why I have spent lots of time to develop this app: allow me to explain the question: whatever application is available as open and/or paid, you will not get the options to split the file based on Time interval or duration. But here you will get this functionality along with other functionality with new flavor; and the main point is that I wanted to develop this using C#. NET and by developing this kind of application I will get a chance to learn something new and even I would utilize my free time into something productive. So I did this and here is the UI of this)J-AXE文件分割器应用程序(J-AXE file splitter application).(.)
图1. JAXE File Splitter UI.(Fig 1. JAXE File Splitter UI.)您可能想知道为什么该应用程序被命名为J-AXE?其实这封信(You might wonder why this application is named J-AXE? Actually the letter)Ĵ(J)来自(came from)下颚(Jawed)和(and)斧头(AXE)是切一些木块.因此,我选择此应用程序名称为(is to cut some wooden block. So, I have chosen this application name as)J轴(J-AXE).(.)
背景(Background)
当然,有一些事情促使我提出了这个想法/应用.上个月,我使用便携式摄像机录制了家庭录像.之后,我在录制的视频中添加了几首歌曲和效果,使其制作成电影,以便可以在家庭成员中分发.现在,我想将此文件分成多个持续时间而不是大小,以便可以将其分成不同的部分,例如第1部分为30分钟,第2部分为45分钟.我在这里和那里搜索了开源,但是我所拥有的所有功能都只能按大小而不按时间间隔分割文件.(Of course, there was something which triggered me to come up with this ideas/application. Last month, I recorded family videos using my camcorder. After that, I added few songs and effects into the recorded video to make it into a movie so that I could distribute this among family members. Now I wanted to split this file into durations instead of size so that I could make it into different parts, something like Part 1 as 30 minutes and Part 2 as 45 Minutes. I searched here and there for open source but everything I got had functionality to splits file only by size not by the time interval.)
然后,这个要求激发了我的化学想象力,提出了一些满足我要求的应用程序,这里是一个应用程序" J-AXE:文件拆分器".(Then this requirement triggered some chemical imagination into my mind to come up with some application to fulfill my requirement and here it is an application “J-AXE: A file Splitter”.)
使用代码(Using the Code)
J-AXE:文件拆分器Windows应用程序非常易于使用.整个解决方案分为2个项目.一个项目是用户界面,第二个项目不过是DLL格式的主要逻辑.将逻辑与UI分离并将逻辑作为DLL的想法,以便任何人都可以轻松使用它,而无需引用我的UI实现.(J-AXE: A file Splitter Windows application is very handy in use. The whole solution is divided into 2 projects. One project would be User interface and the second project would be nothing but our main logic which is in DLL format. The idea to separate logic from UI and make logic as DLL so that anybody can use it easily without referring to my UI implementation.)
让我给您一些有关整个场景的图片演示(类图):(Let me give you some pictorial presentation of the whole scenario (Class Diagram):)
图2.具有JAXE DLL的JAXE文件拆分器的类图.(Fig 2. Class Diagram of JAXE File Splitter with JAXE DLL.)首先,我想解释一下(First, I would like to explain the implementation of)UI部分(UI part).然后,我将解释逻辑部分.(. Then, I will explain the Logic part.)
第1部分:用户界面(PART 1: User Interface)
框图将是这样的:(The block diagram would be something like this:)
图3. JAXE文件拆分器的框图.(Fig 3. Block Digaram of JAXE File Splitter.)在用户界面上,用户将获得以下选项来分割文件:(On UI User will get the below option to split the file:)
- 基于持续时间(持续时间,以秒/分钟为单位)(Based on Duration (Time duration in sec/min))
- 大小(以字节/KB/MB为单位)(Size (in Bytes/KB/MB))
- 和文件数(And Number of files) 根据选择的选项,我们将调用相应的函数来分割文件:(Based on the option selected, we will call the corresponding function to splits the file:)
这是调用相应方法的代码:(Here is the code to call the corresponding method:)
单击"拆分按钮"时,我们将调用按钮单击事件函数以获取输入值,例如要拆分的文件的位置,输出目录和选定的选项.(On click of Split Button, we will call the button click event function to get the inputs values like Location of file to splits, Output directory and selected Option.)
//get the tab selected
int tabSelected = tabControlDuration.SelectedIndex;
//make sure that inputs file and target folder name is provided
if (!string.IsNullOrEmpty(textBoxFileSplit.Text))
{
if (!string.IsNullOrEmpty(textBoxOpFileLocation.Text))
{//get the tab selected for the operation
switch (tabSelected)
{
case 0:
DurationSplit();//call the method to split the file based on duration.
break;
case 1:
SizeSplit();//call the method to split the file based on Size in KB/M/Bytes.
break;
case 2:
NoOfFileSplit();//Call the method to split the the file based on Numbers.
break;
default:
break;
}//end of switch
假设用户点击了"持续时间"标签:(Let’s assume that user has clicked on Duration Tab:)
在此选项下,用户需要提供时间间隔(例如30分钟的间隔)来分割文件,以及他们是否需要时间间隔(以分钟或秒为单位)(默认情况下,以秒为单位).提供所需的输入后,用户需要单击"拆分"按钮.单击此拆分按钮后,用户可以在UI上看到AX的动画,就像AXE下的内容一样.为了显示UI上的动画和文件拆分,我使用了Background Worker的概念.这样,在拆分文件时,不会在UI上冻结或挂起.(Under this option, user needs to provide the Time interval (like 30 minutes of interval) to split the file along with whether they wants the time interval in Minutes or seconds (By default, it would be in seconds). After providing the desired inputs, user needs to click on Split button. On click of this split button, user can see animation of AXE on UI, like something is under AXE. To show the Animation on UI and splitting of files, I have used the concept of BACKGROUND Worker. So that while splitting of the file going on the UI will not get frozen or hang.)
请允许我解释一下有关背景工作者的事情(Allow me to explain something about background worker)((()资源(Source):(:) http://www.albahari.com/threading/part3.aspx(http://www.albahari.com/threading/part3.aspx) ).().)
后台工作者是(Background worker is part of)System.ComponentModel(System.ComponentModel)用于管理工作线程的名称空间.(namespace for managing a worker thread.)
BackgroundWorker
是一个组件,使您可以将长时间运行的任务委托给其他线程.不仅如此.您可以将组件放置在Windows窗体上(它是非UI控件,因此它进入组件托盘).您可以向其注册事件处理程序.它负责在单独的线程中运行长时间运行的任务,同时在主事件处理线程中运行任务以更新控件(以报告结果或进度).(is a component that allows you to delegate a long running task to a different thread. It doesn’t stop with that. You can place the component on a Windows Form (it is a non-UI control, so it goes into the component tray). You can register event handlers with it. It takes care of running the long running task in a separate thread while running the task to update control (to report result or progress) in the main event handling thread.)
BackgroundWorker
有个(has a) RunWorkerCompleted
在(event that fires after the) DoWork
事件处理程序已完成工作.上(event handler has done its job. On) DoWork
,(, the) BackgroundWorker
会打电话给我们(will call our)JAXE DLL(JAXE DLL)分割文件,完成后它将调用(to split the file and when it’s done, it will call) RunWorkerCompleted
以通过UI向用户显示通知消息,并将所有控件重置为初始状态.(to show notification message to the user through UI and reset all the controls to initial states.)
进入代码部分:(Come to the code part:)
如果您看一下我的代码,我已经使用过(If you look at my code, I have used) RunWorkerAsync
通过将参数作为对象传递.意思是说(by passing parameter as object. It means I’m telling) BackgroundWorker
做异步工作.这是执行我们的任务的代码:(to do work asynchronously. Here is the code to perform our task:)
//Method to split the file based on Duration.
private void DurationSplit()
{
var durationIntreval = comboBoxDuration.SelectedIndex;
//Verify the Duration value provided by user
if (!string.IsNullOrEmpty(textBoxDuration.Text))
{
//Convert the duration in seconds
var durationInSeconds = 0.0;
if (durationIntreval == 1)
durationInSeconds=Convert.ToDouble(textBoxDuration.Text)*60;
else
durationInSeconds=Convert.ToDouble(textBoxDuration.Text);
//set the values
var setInPuts = new SetInPuts
{
SourceFileLocation = textBoxFileSplit.Text,
TargetFolderLocation = textBoxOpFileLocation.Text,
DurationToSplit =durationInSeconds,
TabSelected=tabControlDuration.SelectedIndex
};
//Enabled the animation
pictureBox1.Visible = true;
//disable the button
buttonSplit.Enabled = false;
//initialize the BackGround worker
backgroundWorkerForSplitFile = new BackgroundWorker();
//run back ground worker in sync by passing parameter as object.
backgroundWorkerForSplitFile.RunWorkerAsync(setInPuts);
//force the BGW to do some work
backgroundWorkerForSplitFile.DoWork+=new DoWorkEventHandler
(backgroundWorkerForSplitFile_DoWork);
//Force the GBW to perform some of the task when previous job done
backgroundWorkerForSplitFile.RunWorkerCompleted+=
new RunWorkerCompletedEventHandler(backgroundWorkerForSplitFile_RunWorkerCompleted);
}//end of if condition
}//end of the method
我们的(Our) Dowork
将去这里,最终将由后台工作人员致电.(will go here, which will ultimately get called by background worker.)
private static void backgroundWorkerForSplitFile_DoWork
(object sender, DoWorkEventArgs e)
{
//
var split = new JAXE.Jaxe();
var inputToPass = e.Argument as SetInPuts;
if (inputToPass != null)
{
switch (inputToPass.TabSelected)
{
case 0:
split.SplitFileBasedOnDuration(inputToPass.SourceFileLocation,
inputToPass.DurationToSplit,inputToPass.TargetFolderLocation);
break;
case 1:
split.SplitFileBasedOnSize(inputToPass.SourceFileLocation,
inputToPass.SizeToSplit, inputToPass.TargetFolderLocation);
break;
case 2:
split.SplitFileBasedOnNumberOfFiles(inputToPass.SourceFileLocation,
inputToPass.NumOfFileToSplits, inputToPass.TargetFolderLocation);
break;
default:
break;
}
}
}//end of method
完成后,后台工作人员将致电(On completion, the background worker will call) RunWorkerCompleted
使用通知消息更新用户,并重置所有控件.(to update the user with Notification message and alongwith reset all the controls.)
使用后台工作程序,我们将调用主逻辑(JAXE DLL),它将满足我们的拆分文件逻辑.(Using background worker, we will call our main logic (JAXE DLL) which will content our splits file logic.)
如果您看到上面的代码,我们已经调用了如下方法:(If you see the above piece of code, we have called the method like this:)
split.SplitFileBasedOnDuration(inputToPass.SourceFileLocation,
inputToPass.DurationToSplit,inputToPass.TargetFolderLocation);
我打电话了(I have called) SplitFileBasedOnDuration
方法是驻留在我们的外部DLL中的JAXE类的一部分,用于根据时间间隔分割文件.(method which is part of our JAXE class that resides in our external DLL, to split the file based on time interval.)
为了获得输入文件的持续时间,我使用了开源的DLL,但"(To get the duration of input file, I have used open source DLL that is nothing but “) DirectShowLib
“.要了解更多信息,请访问(”. To know more about this, visit) 这个连结(this link) .在获得整个持续时间之后,我开始将文件分成时间间隔.(. After getting the whole duration, I have started splitting the file into time intervals.)
为了根据持续时间分割文件,我参考了输入大小的大小.请看下面的代码.(To split the file based on duration, I have taken the reference with respect to size of input size. Just have a look at the below code.)
//Open the file in read mode
var fsDur = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
//variable to store inputs file total length in seconds
var totalDuration = 0.0;
//get the length of file in seconds
GetVideoLength(inputFile, out totalDuration);
每个字节的持续时间.(Duration of each byte.)
//get the duration of each in interval to split
var durationOfEachFile = Convert.ToDouble(timeDuration);
//get the duration of 1 bytes file
var fractionOfTimeDuration = totalDuration / durationOfEachFile;
对应于每个字节的文件大小w.r.t.用户提供的持续时间:(Size of file corresponding to each byte w.r.t. time duration provided by User:)
//get the size corresponding to duration to split the file
var sizeOfEachFile = (int)Math.Ceiling((double)fsDur.Length / fractionOfTimeDuration);
现在,在拆分源文件后,我们将获得文件总数.(Now we will get the Total Numbers of files after splitting the source file.)
//get the total file to split after comparing time interval with size
var numberOfFiles = (int)Math.Ceiling((double)fsDur.Length / sizeOfEachFile);
//the base file name
var baseFileName = Path.GetFileNameWithoutExtension(inputFile);
//get the extension of the file
var extension = Path.GetExtension(inputFile);
最后,我们将开始逐字节读取源文件并将其放入输出文件中:(Finally, we will start reading the source file byte by byte and will place into output file:)
for (var i = 1; i <= numberOfFiles; i++)
{
//file name after splitting
var outputFile = new FileStream(outPutLocation + "\\"
+ baseFileName + "_" + i.ToString().PadLeft(5, Convert.ToChar("0"))
+ extension, FileMode.Create, FileAccess.Write);
var bytesRead = 0;
//array of bytes to hold the piece of file data after splitting
var buffer = new byte[sizeOfEachFile];
//split the file byte by byte
if ((bytesRead = fsDur.Read(buffer, 0, sizeOfEachFile)) > 0)
outputFile.Write(buffer, 0, bytesRead);
outputFile.Close();
}
输出文件名将采用这种格式(The output files name would in this format) SourceFilename_Numericvalue.extension
.(.)
整个逻辑如下:(The whole logic would be as below:)
//Split the file based on duration
//Note: There might be a chances where exact duration of the file
//would not be same as user provided. deviation of few seconds
public void SplitFileBasedOnDuration(string inputFile,
double timeDuration,string outPutLocation)
{
//Open the file in read mode
var fsDur = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
//variable to store inputs file total length in seconds
var totalDuration = 0.0;
//get the length of file in seconds
GetVideoLength(inputFile, out totalDuration);
//get the duration of each in interval to split
var durationOfEachFile = Convert.ToDouble(timeDuration);
//get the duration of 1 bytes file
var fractionOfTimeDuration = totalDuration / durationOfEachFile;
//get the size corresponding to duration to split the file
var sizeOfEachFile = (int)Math.Ceiling((double)fsDur.Length / fractionOfTimeDuration);
//get the total file to split after comparing time interval with size
var numberOfFiles = (int)Math.Ceiling((double)fsDur.Length / sizeOfEachFile);
//the base file name
var baseFileName = Path.GetFileNameWithoutExtension(inputFile);
//get the extension of the file
var extension = Path.GetExtension(inputFile);
for (var i = 1; i <= numberOfFiles; i++)
{
//file name after splitting
var outputFile = new FileStream(outPutLocation +
"\\" + baseFileName + "_" + i.ToString().PadLeft(5, Convert.ToChar("0")) +
extension, FileMode.Create, FileAccess.Write);
var bytesRead = 0;
//array of bytes to holed the piece of file data after splitting
var buffer = new byte[sizeOfEachFile];
//split the file byte by byte
if ((bytesRead = fsDur.Read(buffer, 0, sizeOfEachFile)) > 0)
outputFile.Write(buffer, 0, bytesRead);
outputFile.Close();
}
//close the File stream
fsDur.Close();
//return "Done!";
}
最终,在分割源文件之后,我们的文件将可以使用.我已经在几个扩展源文件中对此进行了测试,它可以完美运行.但是我还没有在所有类型的源文件上对此进行测试.可能有几个文件无法使用.如果您发现一些错误,请告诉我.我很高兴收到大家的来信.(Finally our files would be ready to use after splitting the source file. I have tested this on few extension source files, it works perfectly. But I have not tested this on all types of source files. Might be few files would not work. Please let me know if you find some bugs. I would be happy to hear from all of you.)
兴趣点(Points of Interest)
第一次使用后台工作程序的概念时,当您不想在执行一些复杂/冗长的过程时冻结UI时,我发现它在Windows应用程序中非常有趣且有用.基于持续时间拆分文件也非常具有挑战性,以某种方式我克服了这些问题,但是输出文件的持续时间仍然存在一些偏差(秒的分数).(The first time I used the concept of background worker and I found it very interesting and useful in Windows application when you don’t want your UI to get frozen while doing some complex/lengthy process. Splitting the file based on duration was also very challenging, somehow I overcome those issues, but still there is some deviation (fraction of seconds) in the time duration of output files.)
要记住的要点(Points to Remember)
BackgroundWorker
使用(uses the) 线程池(thread pool) ,这意味着您永远不要致电(, which means you should never call) 中止(Abort) 在一个(on a) BackgroundWorker
线.(thread.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C#3.0 C# C#2.0 WinXP Vista .NET2.0 Visual-Studio VS2008 QA Dev 新闻 翻译