C#——一个简单的文件管理器

最近在紧张的学习C#,说实话对C#之前没有太多的接触过,只知道C#的特性与java很相似,接触了之后才发现C#跟java相比区别不是很多,但它是一门实现程序能力比Java还要好的语言(仅代表个人观点)。

有许多新手在学习编程语言的时候,都会在递归上面卡住,理解和应用起来会十分的吃力,所以我就自己尝试用递归写了一个很简单很简单很简单的文件管理程序,说它简单是因为他真的没有什么难度,都是很底层的循环和递归,也就只有130多行代码,只是希望能够帮助大家理解应用递归。如果你一点编程基础木有,那请不要直接来尝试递归和各种循环,请一步步扎实的从头学起。

这个很简单很简单很简单的文件管理程序提供如下几个功能:检索用户输入路径下文件的总数量;检索用户输入路径下文件夹的数量;检索用户输入路径下所有结尾与输入字符匹配的文件数量。这么说可能有点儿抽象,先贴一张程序运行的结果图片。

我分别使用这个小程序检索了我C盘下Autodesk文件夹内的文件总数,文件夹总数和txt文件总数,最后退出程序。然后我来到了Autodesk文件夹,右键属性了一下,证实数量确实是正确的。而至于txt的数量,我在文件夹窗口搜索栏输入txt,一共182个结果,然而我一个一个数过了,有6个是开头为txt的,所以176是准确无误的。如果你想要让我们代码的功能编程包含txt这三个字符而不是以这三个字符结尾,只需要在后面进行简单修改,这里先不赘述。

好了闲话不多说直接贴上代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;//需要引入
using System.Threading;//需要引入

namespace FilesManager
{
    class Program
    {
        //FilesNumber方法
        #region
        static int FilesNumber(string path)
        {
            int count = 0;
            try
            {
                var files = Directory.GetFiles(path);
                count = files.Length;
                var directories = Directory.GetDirectories(path);
                foreach (var direc in directories)
                {
                    count += FilesNumber(direc);
                }
            }
            catch (UnauthorizedAccessException exception)
            {
                Console.WriteLine(exception.Message);
            }
            return count;
        }
        #endregion

        //DirectoriesNumber方法
        #region
        static int DirectoriesNumber(string path)
        {
            int count = 0;
            try
            {
                var directories = Directory.GetDirectories(path);
                count = directories.Length;

                foreach (var direc in directories)
                {
                    count += DirectoriesNumber(direc);
                }
            }
            catch (UnauthorizedAccessException exception)
            {
                Console.WriteLine(exception.Message);
            }
            return count;
        }
        #endregion

        //FindExtension方法
        #region
        static int FindExtension(string path, string extension)
        {
            int count = 0;
            try
            {
                var files = Directory.GetFiles(path);
                foreach (var file in files)
                {
                    if (file.ToLower().EndsWith(extension)) count++;
                }
                var directories = Directory.GetDirectories(path);

                foreach (var direc in directories)
                {
                    count += FindExtension(direc, extension);
                }
            }
            catch (UnauthorizedAccessException exception)
            {
                Console.WriteLine(exception.Message);
            }
            return count;
        }
        #endregion

        //Main方法
        #region
        static void Main(string[] args)
        {
            string path, extension, order;
            Thread.Sleep(1200);
            Console.WriteLine("程序开始,Designed By Mr.Losers");
            Thread.Sleep(1200);
            Console.WriteLine("特别鸣谢:何掌柜的");
            Thread.Sleep(1200);
            Console.WriteLine();
            Console.Write("计算路径下文件数量请输入0\n计算路径下文件夹子数请输入1\n");
            Console.Write("搜索路径下文件名匹配数量请输入2\n退出程序请输入q\n");

            do
            {
                order = Console.ReadLine();
                if (order == "0")
                {
                    Console.Write("文件管理系统已经就绪!\n请输入你要查找的路径:\n");
                    path = Console.ReadLine();
                    Console.WriteLine("该路径下文件总数为:{0}", FilesNumber(path));
                    order = Console.ReadLine();
                }
                if (order == "1")
                {
                    Console.Write("文件管理系统已经就绪!\n请输入你要查找的路径:\n");
                    path = Console.ReadLine();
                    Console.WriteLine("该路径下文件夹总数为:{0}", DirectoriesNumber(path));
                    order = Console.ReadLine();
                }
                if (order == "2")
                {
                    Console.Write("文件管理系统已经就绪!\n请输入你要查找的路径:\n");
                    path = Console.ReadLine();
                    Console.WriteLine("请输入你想要匹配的文件名称:");
                    extension = Console.ReadLine();
                    Console.WriteLine("符合名称的文件总数为:{0}", FindExtension(path, extension));
                    order = Console.ReadLine();
                }
                if (order == "q")
                    break;
                else
                {
                    Console.WriteLine("输入错误请重新输入:");
                }
            }
            while (true);

            Console.Write("Thanks for using!");
            Thread.Sleep(2000);
        }
        #endregion
    }
}

贴完代码后,来简单说明一下里面包含的东西。

首先要说几个点:

第一个是在代码中我使用了多次var,var是C#中很方便一种用法,让编译器自动判断类型。比如这里的Directory.GetFiles(path);

返回的是一个string类型的数组,是包含path路径下的每个文件的路径数组。var files = Directory.GetFiles()相当于string [] files = Directory.GetFiles(path)

第二个是预处理指令,#region和#endregion,方便管理代码,收起一块区域内的代码

第三个是try catch语句,在本程序中我们每一个文件搜索的方法都使用了该语句,因为无论是C盘还是D盘等盘符都会有文件我们是没有访问权限的,所以我们要catch UnauthorizedAccessException,并且把此exception的信息打印出来,这样一来我们可以知道那些文件没有被进一步访问,二来程序不会因为exception而中断。

第四个是我们在开始需要引入两个命名空间,因为我们用到的方法Thread.Sleep()需要引入System.Threading;用到的GetFiles()和GetDirectories()需要引入System.IO;

下面我们按照顺序来看代码,先来讲FilesNumber方法,三个方法都使用了递归的思想,此方法需要传入一个形参path,既搜索的路径。count为计数器,计算文件的个数。

首先对我们传入路径path中的所有文件计数,所以count = files.Length,然后取出path中所有的directory,也就是可以继续向下探索的文件夹;接下来是很重要的一步——递归,对每个path中取出的directory再继续执行本方法,并与当前count相加得到新的count数值,层层向下,直到不存在可以继续向下探索的文件夹为止。

在方法中调用自己是递归的基本思路。我们假设path下有10个文件,其中有3个文件夹path1,path2,path3,那实际上这段代码的执行过程是:count(path)= path路径下的文件数量+count(path1)+country(path2)+count(path3),然后path1,path2,path3内还有文件和文件夹,于是分解仍在继续。

举一个数学例子帮助大家理解:

128 = 64 + 64 = 64 + (32 +32)= 64 + ((16+16)+(16+16))= 64 + (((8+8)+(8+8))+((8+8)+(8+8))),虽然不完全一样,

但道理是差不多的,都是一个层层分解的过程。我已经用生命在解释了,还是没懂得请多思考思考,或者另谋高就把。。。。

解释完了FilesNumber的话,DirectoriesNumnber是比FilesNumber还要简单的同样使用了递归的方法,这就略过了。

FindExtension方法只是做了些许的改变,首先方法传入两个参数,一个路径path,一个匹配的扩展名extension,这里注意我使用的两个方法,ToLower方法确保了大小写的匹配文件都可以找到,EndsWith()是后端匹配,当然我们也可以使用StartWith()和Contains(),如果你搜索的文件数量很少,并且我们还可以找到文件后,输入它当前的路径,这些就交给读者自己去修改吧,其实是比较简单的,我为了保证程序的简洁就没有输出路径,100多条路径一下输出出来也是挺痛苦的。

接下来来到Main方法,注意Java中Main方法都是小写的main,而C#中需要大写。

Main方法的前半部分都是定义和输出使用方法。因为我有一点儿轻微的强迫症,认为输出时加入延迟会让人感觉更加舒服,并且会认真看屏幕上出现的字。所以我加入了Sleep方法,我一开始设定的是Sleep2000毫秒你敢信。。。。

在输出文字后的do while循环才是程序的主体。其实完全可以改用while,只是不知道为啥我写的时候,用了个do while,你会发现我后面while的条件是true,也就是他会一直执行,直到用户输入Q后break出来。。。。。

这个循环中首先会要求你输入,根据前面提示用户会知道输入0、1、2、q来选择功能,然后程序会根据用户输入不同的字符来执行不通的功能即调用不同的方法,执行之后立刻重置,以准备下一次使用。因为输入的是字符串,我就没有转换为int类型然后使用switch语句。

其实现在仔细看看这个程序真的是很简单很简单很简单的,最简单的递归,最简单的循环,所以我们不得不赞叹代码真的是很神奇的东西,我到现在还记得前两天把这个小东西给不懂编程的女票何掌柜看的时候她竟然以为这个小程序很强大,能卖钱,也是秀逗了。

最后还是希望能够帮到大家,C#真的是一门很好的语言。

另:如果大家发现了一些错误或者有更好的改进还请不吝赐教,请邮箱、私信或者微博联系我。

2015.4.5 15:39

By Mr.Losers

时间: 2024-08-02 15:13:26

C#——一个简单的文件管理器的相关文章

Java实现的一个简单的下载器

package com.shawearn.download;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.EOFException;import java.io.File;http://www.huiyi8.com/jiaoben/import j

可视化程序设计基础(三)——一个简单的播放器(并不)

本次的作业是制作一个简单的播放器,功能仅限于播放视频和音频,虽说是简单的播放器,但其中还是有很多细节需要注意的. 问题一:布局 本来这个问题不应该是一个问题了,之前老师讲过的Stackpanel和Grid等对于布局一个播放器来说绰绰有余,但上次上课老师提到的NavigationView令我十分感兴趣,这是一个uwp应用程序中随处可见的一种布局,节省了开发者很多的时间. 所以我就着手于建立这个NavigationView了,首先我看了一下XAML Controls Gallery,然而其中关于Na

[SimplePlayer] 实现一个简单的播放器

简单的播放器需要实现一个最基本的功能:播放视频文件. 实现这个功能需要包含以下几个步骤: 从视频文件中提取视频图像 在屏幕上显示视频图像 视频帧的同步,也就是保证视频图像在合适的时间在屏幕上显示 从视频文件中提取音频 向音频设备输出音频 音频同步,也就是保证合适的时间输出合适的音频 多线程处理 音视频同步 本实现是通过ffmpeg来实现音视频的提取,通过sdl2来实现音视频的输出,版本如下: libavutil 56. 19.100 / 56. 19.100 libavcodec 58. 23.

一个简单的配置管理器(SettingManager)

在很多.net开发的项目中,我们几乎都会使用到一些自定义的参数,比如说第三方的配置参数之类的. 他们的特点是:1.系统全局 2,可以做成键值对(Dictionary). 我们可以将这些参数放到Web.config,xml或者数据库表中,当然部分不常变的可以直接写在程序中. 为了方便我通常喜欢将他们统放在一个配置管理器中,然后希望别人使用时, 可以像使用AppSetings中的参数一样 初看起来还是比较容易实现,在ConfiguratonManager中定义一个公开属性AppSettings就好了

C++写一个简单的解析器(分析C语言)

该方案实现了一个分析C语言的词法分析+解析. 注意: 1.简单语法,部分秕.它可以在本文法的基础上进行扩展,此过程使用自上而下LL(1)语法. 2.自己主动能达到求First 集和 Follow 集. 3.处终结符外(有些硬编码的成分),终结符的文法能够自己定义,也就是说读者能够自己定义文法. 4.为方便理解.C语言的文法描写叙述写成中文. 5.程序将词法分析和语法分析结合起来.词法分析的结果作为语法分析的输入. 6.终于结果在控制台显示的有:词法分析.First集.Follow集.Select

ffmpeg+sdl教程----编写一个简单的播放器4(让程序更模块化)

来源:http://blog.csdn.net/mu399/article/details/5815444 音频和视频之间的同步,再那之前需要先做一些准备工作. 为了让程序更模块化,便于扩展,需要把原来main函数中的各个功能模块代码分离出来放在相应的函数中.该教程和上个教程相比代码量和难度都增加很多,比上个教程使用了更多的线程,一定要理解清楚各个函数和数据结构之间的关联以及线程之间如何协同工作. [c-sharp] view plaincopy // ffmpegExe.cpp: 主项目文件.

ffmpeg+sdl教程----编写一个简单的播放器5(同步视频到音频)

来源:http://blog.csdn.net/mu399/article/details/5816566 个人认为,这这部分教程的新增代码量虽然不是最多的,难度却是最大的,重复看了多次才明白,因为有两个问题的困扰,搞得还不清楚: 1.音频和视频既然都有各自的时间戳,各自按各自的时间戳来播放不就行了,为什么还需要同步呢? 2.如果要把视频同步到音频,怎么同步?或者说以什么标准来同步? 第一个问题的答案可能是,一是音频和视频的开始播放的时间是不一样,二是播放每帧音频或视频时可能必须把解码数据,视频

ffmpeg+sdl教程----编写一个简单的播放器3(为视频加入音频)

来源:http://blog.csdn.net/mu399/article/details/5814901 上个教程实现了视频的简单播放,但那是个哑巴电影,完全没有声音. 这个教程第一次用到了SDL的线程,涉及到了两个线程间的同步协调,有几个地方需要特别留意,SDL_OpenAudio库函数会打开音频设备(0是恢 复,其他的是暂停),SDL_PauseAudio库函数可以暂停或者恢复audio_callback函数的执行,程序中的这行代码 “SDL_PauseAudio(0);”执行后,让aud

第二十四篇-用VideoView制作一个简单的视频播放器

这是一个播放本地视频的播放器,videoUrl1是手机里放置视频的路径 效果图: MainActivity.java package com.example.aimee.videotest; import android.Manifest; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.support.annotation.NonN