C#树图显示目录下所有文件以及文件大小
我们在打开某个目录属性时,可以查看到有大小信息.如下图
而一个目录(文件夹)System.IO.Directory是没有FileSize或者Length属性的.
目录(文件夹)的大小是指该目录下所有子目录和所有文件大小的累加,按字节为单位.
新建窗体应用程序GetFolderFileSizeDemo,将默认的Form1重命名为FormFolderFileSize,
窗体FormFolderFileSize设计器代码如下
文件FormFolderFileSize.Designer.cs
namespace GetFolderFileSizeDemo
{
partial class FormFolderFileSize
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnSelect = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.txtFolderPath = new System.Windows.Forms.TextBox();
this.tvFile = new System.Windows.Forms.TreeView();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.rtxtMessage = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// btnSelect
//
this.btnSelect.Location = new System.Drawing.Point(659, 12);
this.btnSelect.Name = "btnSelect";
this.btnSelect.Size = new System.Drawing.Size(75, 23);
this.btnSelect.TabIndex = 0;
this.btnSelect.Text = "选择目录";
this.btnSelect.UseVisualStyleBackColor = true;
this.btnSelect.Click += new System.EventHandler(this.btnSelect_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 12);
this.label1.TabIndex = 1;
this.label1.Text = "请选择目录";
//
// txtFolderPath
//
this.txtFolderPath.Location = new System.Drawing.Point(102, 11);
this.txtFolderPath.Name = "txtFolderPath";
this.txtFolderPath.ReadOnly = true;
this.txtFolderPath.Size = new System.Drawing.Size(551, 21);
this.txtFolderPath.TabIndex = 2;
//
// tvFile
//
this.tvFile.ImageIndex = 0;
this.tvFile.ImageList = this.imageList1;
this.tvFile.Location = new System.Drawing.Point(14, 38);
this.tvFile.Name = "tvFile";
this.tvFile.SelectedImageIndex = 0;
this.tvFile.Size = new System.Drawing.Size(573, 480);
this.tvFile.TabIndex = 3;
this.tvFile.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvFile_AfterSelect);
//
// imageList1
//
this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// rtxtMessage
//
this.rtxtMessage.Location = new System.Drawing.Point(593, 38);
this.rtxtMessage.Name = "rtxtMessage";
this.rtxtMessage.ReadOnly = true;
this.rtxtMessage.Size = new System.Drawing.Size(377, 480);
this.rtxtMessage.TabIndex = 4;
this.rtxtMessage.Text = "";
//
// FormFolderFileSize
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(982, 548);
this.Controls.Add(this.rtxtMessage);
this.Controls.Add(this.tvFile);
this.Controls.Add(this.txtFolderPath);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnSelect);
this.Name = "FormFolderFileSize";
this.Text = "获取指定目录下的累计文件大小,并按树图显示";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnSelect;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtFolderPath;
private System.Windows.Forms.TreeView tvFile;
private System.Windows.Forms.RichTextBox rtxtMessage;
private System.Windows.Forms.ImageList imageList1;
}
}
窗体FormFolderFileSize相关代码如下:
文件FormFolderFileSize.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GetFolderFileSizeDemo
{
public partial class FormFolderFileSize : Form
{
public FormFolderFileSize()
{
InitializeComponent();
imageList1.Images.Add(Properties.Resources.file);//文件图标
imageList1.Images.Add(Properties.Resources.folder);//目录(文件夹)图标
}
private void btnSelect_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
folderBrowser.SelectedPath = "D:\\";
DialogResult dialog = folderBrowser.ShowDialog();
if (dialog != DialogResult.OK)
{
return;
}
string selectedFolder = folderBrowser.SelectedPath;
txtFolderPath.Text = selectedFolder;
rtxtMessage.Clear();
tvFile.Nodes.Clear();
TreeNodeCollection nodes = tvFile.Nodes;
TreeNode rootNode = new TreeNode(Path.GetFileName(selectedFolder))
{
ImageIndex = 1,
SelectedImageIndex = 1,
Tag = selectedFolder //记录文件或者文件夹的路径
};
nodes.Add(rootNode);
BindTreeView(rootNode.Nodes, selectedFolder);
rootNode.Expand();
tvFile.SelectedNode = rootNode;
}
private void BindTreeView(TreeNodeCollection nodes, string directoryPath)
{
//读取当前目录下的下一级目录,将其添加到队列中
string[] directories = Directory.GetDirectories(directoryPath);
for (int i = 0; i < directories.Length; i++)
{
TreeNode treeNode = new TreeNode(Path.GetFileName(directories[i]))
{
ImageIndex = 1,
SelectedImageIndex = 1,
Tag = directories[i] //记录文件或者文件夹的路径
};
nodes.Add(treeNode);
BindTreeView(treeNode.Nodes, directories[i]);
}
//读取当前目录下的所有文件,直接显示到树图中
string[] files = Directory.GetFiles(directoryPath);
for (int i = 0; i < files.Length; i++)
{
nodes.Add(new TreeNode(Path.GetFileName(files[i]))
{
ImageIndex = 0,
SelectedImageIndex = 0,
Tag = files[i] //记录文件或者文件夹的路径
});
}
}
private void tvFile_AfterSelect(object sender, TreeViewEventArgs e)
{
rtxtMessage.Clear();
TreeNode treeNode = e.Node;
if (treeNode == null)
{
return;
}
string path = Convert.ToString(treeNode.Tag);
long totalSize = 0L;
if (treeNode.ImageIndex == 0)
{
//如果是文件,就直接读取大小
totalSize = GetFileSize(path);
rtxtMessage.AppendText($"【文件】\n路径:【{path}】\n文件大小:【{GetFileSizeDescription(totalSize)}】");
}
else
{
//如果是目录(文件夹),就递归读取所有文件
totalSize = GetFolderSize(path);
rtxtMessage.AppendText($"【目录】\n路径:【{path}】\n文件大小:【{GetFileSizeDescription(totalSize)}】");
}
}
/// <summary>
/// 获取指定文件的大小,按字节为单位
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private long GetFileSize(string fileName)
{
if (!File.Exists(fileName))
{
return 0;
}
return new FileInfo(fileName).Length;
}
/// <summary>
/// 递归遍历所有文件,获取目录(文件夹)累计占用的文件大小,按字节为单位
/// </summary>
/// <param name="folderPath"></param>
/// <returns></returns>
private long GetFolderSize(string folderPath)
{
if (!Directory.Exists(folderPath))
{
return 0;
}
long totalSize = 0L;
Queue<string> directoryCollection = new Queue<string>();
directoryCollection.Enqueue(folderPath);
while (directoryCollection.Count > 0)
{
string directoryPath = directoryCollection.Dequeue();
//读取当前目录下的下一级目录,将其添加到队列中
string[] directories = Directory.GetDirectories(directoryPath);
for (int i = 0; i < directories.Length; i++)
{
directoryCollection.Enqueue(directories[i]);
}
//读取当前目录下的所有文件,计算字节树
string[] files = Directory.GetFiles(directoryPath);
for (int i = 0; i < files.Length; i++)
{
totalSize += GetFileSize(files[i]);
}
}
return totalSize;
}
/// <summary>
/// 获取文件大小描述
/// </summary>
/// <param name="fileSize"></param>
/// <returns></returns>
private string GetFileSizeDescription(long fileSize)
{
const long KByte = 1024L;
const long MByte = 1024L * KByte;
const long GByte = 1024L * MByte;
if (fileSize >= GByte)
{
return ((double)fileSize / GByte).ToString("N2") + "\x20GB";
}
else if (fileSize >= MByte)
{
return ((double)fileSize / MByte).ToString("N2") + "\x20MB";
}
else if (fileSize >= KByte)
{
return (fileSize / KByte).ToString() + "\x20KB";//KB用整数表示
}
return fileSize + "\x20字节";
}
}
}
显示如图: