文件操作
File类
File类支持对文件的基本操作,包括提供用于创建、复制、删除、移动和打开文件的静态方法,并协助创建FileStream对象。由于所有的File类的方法都是静态的,所以如果只想执行一个操作,那么使用File方法的效率比使用相应的FileInfo实例方法可能更高。
方法 | 说明 |
---|---|
Create | 在指定路径中创建文件 |
Copy | 将现有文件复制到新文件 |
Exists | 确定指定的文件是否存在 |
GetCreationTime | 返回指定文件或目录的创建日期和时间 |
GetLastAccessTime | 返回上次访问指定文件或目录的日期和时间 |
GetLastWriteTime | 返回上次写入指定文件或目录的日期和时间 |
Move | 将指定文件移到新位置,并提供指定新文件名的选项 |
Open | 打开指定路径上的FileStream |
OpenRead | 打开现有文件以进行读取 |
OpenText | 打开现有UTF-8编码文本文件以进行读取 |
OpenWrite | 打开现有文件以进行写入 |
FileInfo类
FileInfo类和File类之间许多方法调用都是相同的,但是FileInfo类没有静态方法,仅可以用于实例化对象。File类是静态类,所以它的调用需要字符串参数为每一个方法调用规定文件位置,因此如果要在对象上进行单一方法调用,则可以使用静态File类,反之则使用FileInfo类。
属性 | 说明 |
---|---|
CreationTime | 获取或设置当前FileSystemInfo对象的创建时间 |
DirectoryName | 获取表示目录的完整路径的字符串 |
Exists | 获取指示文件是否存在的值 |
Extension | 获取表示文件扩展名部分的字符串 |
FullName | 获取目录或文件的完整目录 |
Length | 获取当前文件的大小 |
Name | 获取文件名 |
例子
使用File类在项目文件夹下创建文件,在创建文件时,需要判断该文件是否已经存在,如果存在,弹出信息提示;否则,创建文件,并在ListView列表中显示文件的名称、扩展名、大小及修改时间等信息。
控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rBOS1GrP-1589477028336)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476058224.png)]
逻辑:
private void button1_Click(object sender, EventArgs e)
{
if (File.Exists(textBox1.Text))//判断要创建的文件是否存在
{
MessageBox.Show("该文件已经存在,请重新输入");
}
else
{
File.Create(textBox1.Text);//创建文件
FileInfo fInfo = new FileInfo(textBox1.Text);//创建FileInfo对象
ListViewItem li = new ListViewItem();
li.SubItems.Clear();
li.SubItems[0].Text = fInfo.Name;//显示文件名称
li.SubItems.Add(fInfo.Extension);//显示文件扩展名
li.SubItems.Add(fInfo.Length / 1024 + "KB");//显示文件大小
li.SubItems.Add(fInfo.LastWriteTime.ToString());//显示文件修改时间
listView1.Items.Add(li);
}
}
Directory类
Directory类用于文件夹的典型操作,如复制、移动、重命名、创建和删除等,另外,也可将其用于获取和设置与目录的创建、访问及写入操作相关的DateTime信息。
方法 | 说明 |
---|---|
CreateDirectory | 创建指定路径中的目录 |
Delete | 删除指定的目录 |
Exists | 确定给定路径是否引用磁盘上的现有目录 |
GetCreationTime | 获取目录的创建日期和时间 |
GetCurrentDirectory | 获取应用程序的当前工作目录 |
GetDirectories | 获取指定目录中子目录的名称 |
GetFiles | 返回指定目录中的文件的名称 |
GetLogicalDrives | 检索此计算机上格式为“<驱动器号>:\”的逻辑驱动器的名称 |
GetParent | 检索指定路径的父目录,包括绝对路径和相对路径 |
Move | 将文件或目录及其内容移到新位置 |
SetCreationTime | 为指定的文件或目录设置创建日期和时间 |
SetCurrentDirectory | 将应用程序的当前工作目录设置为指定的目录 |
DirectoryInfo类
DirectoryInfo类和Directory类之间的关系与FileInfo类和File类之间的关系十分类似。
属性 | 说明 |
---|---|
Attributes | 获取或设置当前Filesysteminfo的Fileattributes |
CreationTime | 获取或设置当前FileSystemInfo对象的创建时间 |
Exists | 获取指示目录是否存在的值 |
FullName | 获取目录或文件的完整目录 |
Parent | 获取指定子目录的父目录 |
Name | 获取DirectoryInfo实例的名称 |
例子
遍历指定驱动器下的所有文件夹及文件名称。
控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5zM16ge-1589477028338)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589475994301.png)]
逻辑:
//获取所有驱动器,并显示在ComboBox中
private void Form1_Load(object sender, EventArgs e)
{
string[] dirs = Directory.GetLogicalDrives();//获取计算上的逻辑驱动器的名称
if (dirs.Length > 0)//如果有驱动器
{
for (int i = 0; i < dirs.Length; i++)//遍历驱动器
{
comboBox1.Items.Add(dirs[i]);//将驱动名称添加到下拉项中
}
}
}
//选择驱动器
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
if (((ComboBox)sender).Text.Length > 0)//如果在下拉项中选择了值
{
treeView1.Nodes.Clear();//清空treeView1控件
TreeNode TNode = new TreeNode();//实例化TreeNode
//将驱动器下的文件夹及文件名称添加到treeView1控件上
Folder_List(treeView1, ((ComboBox)sender).Text, TNode, 0);
}
}
#region 显示文件夹下所有子文件夹及文件的名称
/// <summary>
/// 显示文件夹下所有子文件夹及文件的名称
/// </summary>
/// <param Sdir="string">文件夹的目录</param>
/// <param TNode="TreeNode">节点</param>
/// <param n="int">标识,判断当前是文件夹,还是文件</param>
private void Folder_List(TreeView TV, string Sdir, TreeNode TNode, int n)
{
if (TNode.Nodes.Count > 0)//如果当前节点下有子节点
if (TNode.Nodes[0].Text != "")//如果第一个子节点的文本为空
return;//退出本次操作
if (TNode.Text == "")//如果当前节点的文本为空
Sdir += "\\";//设置驱动器的根路径
DirectoryInfo dir = new DirectoryInfo(Sdir);//实例化DirectoryInfo类
try
{
if (!dir.Exists)//判断文件夹是否存在
{
return;
}
DirectoryInfo dirD = dir as DirectoryInfo;//如果给定参数不是文件夹,则退出
if (dirD == null)//如果文件夹是否为空
{
TNode.Nodes.Clear();//清空当前节点
return;
}
else
{
if (n == 0)//如果当前是文件夹
{
if (TNode.Text == "")//如果当前节点为空
TNode = TV.Nodes.Add(dirD.Name);//添加文件夹的名称
else
{
TNode.Nodes.Clear();//清空当前节点
}
TNode.Tag = 0;//设置文件夹的标识
}
}
FileSystemInfo[] files = dirD.GetFileSystemInfos();//获取文件夹中所有文件和文件夹
//对单个FileSystemInfo进行判断,遍历文件和文件夹
foreach (FileSystemInfo FSys in files)
{
FileInfo file = FSys as FileInfo;//实例化FileInfo类
if (file != null)//如果是文件的话,将文件名添加到节点下
{
FileInfo SFInfo = new FileInfo(file.DirectoryName + "\\" + file.Name);//获取文件所在路径
TNode.Nodes.Add(file.Name);//添加文件名
TNode.Tag = 0;//设置文件标识
}
else//如果是文件夹
{
TreeNode TemNode = TNode.Nodes.Add(FSys.Name);//添加文件夹名称
TNode.Tag = 1;//设置文件夹标识
TemNode.Nodes.Add("");//在该文件夹的节点下添加一个空文件夹,表示文件夹下有子文件夹或文件
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
#endregion
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (((TreeView)sender).SelectedNode == null)//如当前节点为空
return;
//将指定目录下的文件夹及文件名称清加到treeView1控件的指定节点下
Folder_List(treeView1, ((TreeView)sender).SelectedNode.FullPath.Replace("\\\\", "\\"),((TreeView)sender).SelectedNode, 0);
}
DriveInfo类
DriveInfo类用来提供对有关驱动器的信息的访问,使用DriveInfo类可以确定哪些驱动器可用,以及这些驱动器的类型,还可以通过查询来确定驱动器的容量和可用空闲空间。
DriveInfo类最主要的一个方法是GetDrives方法,该方法用来检索计算机上的所有逻辑驱动器的驱动器名称。
例子
使用DriveInfo类获取本地计算机上的所有磁盘驱动器,当用户选择某个驱动器时,将其包含的所有文件夹名称及创建时间显示到ListView列表中。
控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WbB6oLmx-1589477028342)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476197015.png)]
逻辑:
private void Form1_Load(object sender, EventArgs e)
{
DriveInfo[] dInfos = DriveInfo.GetDrives();//获取本地所有驱动器
foreach (DriveInfo dInfo in dInfos)//遍历获取到的驱动器
{
comboBox1.Items.Add(dInfo.Name);//将驱动器名称添加到下拉列表中
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string[] strDirs = Directory.GetDirectories(comboBox1.Text);//获取指定磁盘下的所有文件夹
foreach (string strDir in strDirs)//遍历获取到的文件夹
{
ListViewItem li = new ListViewItem();
li.SubItems.Clear();
DirectoryInfo dirInfo = new DirectoryInfo(strDir);//使用遍历到的文件夹创建DirectoryInfo对象
li.SubItems[0].Text = dirInfo.Name;//显示文件夹名称
li.SubItems.Add(dirInfo.CreationTime.ToString());//显示文件夹创建时间
listView1.Items.Add(li);
}
}
FileStream类
方法 | 说明 |
---|---|
Close | 关闭当前流并释放与之关联的所有资源 |
Lock | 允许读取访问的同时防止其他进程更改FileStream |
Read | 从流中读取字节块并将该数据写入给定缓冲区中 |
ReadByte | 从文件中读取一个字节,并将读取位置提升一个字节 |
Seek | 将该流的当前位置设置为给定值 |
SetLength | 将该流的长度设置为给定值 |
Unlock | 允许其他进程访问以前锁定的某个文件的全部或部分 |
Write | 使用从缓冲区读取的数据将字节块写入该流 |
例子
使用不同的方式打开文件,其中包含“读写方式打开”、“追加方式打开”、“清空后打开”和“覆盖方式打开”,然后对其进行写入和读取操作。
控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvfjjvAH-1589477028343)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476439445.png)]
逻辑
FileMode fileM = FileMode.Open;//声明一个FileMode对象,用来记录要打开的方式
//执行读写操作
private void button1_Click(object sender, EventArgs e)
{
string path = textBox1.Text;//获取打开文件的路径
try
{
using (FileStream fs = File.Open(path, fileM))//以指定的方式打开文件
{
if (fileM != FileMode.Truncate)//如果在打开文件后不清空文件
{
Byte[] info = new UTF8Encoding(true).GetBytes(textBox2.Text);//将要添加的内容转换成字节
fs.Write(info, 0, info.Length);//向文件中写入内容
}
}
using (FileStream fs = File.Open(path, FileMode.Open))//以读/写方式打开文件
{
byte[] b = new byte[1024];//定义一个字节数组
UTF8Encoding temp = new UTF8Encoding(true);//实现UTF-8编码
string pp = "";
while (fs.Read(b, 0, b.Length) > 0)//读取文本中的内容
{
pp += temp.GetString(b);//累加读取的结果
}
MessageBox.Show(pp);//显示文本中的内容
}
}
catch//如果文件不存在,则发生异常
{
if (MessageBox.Show("该文件不存在,是否创建文件。", "提示", MessageBoxButtons.YesNo) == DialogResult.Yes)//显示提示框,判断是否创建文件
{
FileStream fs = File.Open(path, FileMode.CreateNew);//在指定的路径下创建文件
fs.Dispose();//释放流
}
}
}
//选择打开方式
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (((RadioButton)sender).Checked == true)//如果单选按钮被选中
{
switch (Convert.ToInt32(((RadioButton)sender).Tag.ToString()))//判断单选项的选中情况
{
//记录文件的打开方式
case 0: fileM = FileMode.Open; break;//以读/写方式打开文件
case 1: fileM = FileMode.Append; break;//以追加方式打开文件
case 2: fileM = FileMode.Truncate; break;//打开文件后清空文件内容
case 3: fileM = FileMode.Create; break;//以覆盖方式打开文件
}
}
}
例子
登陆创建日志。
登陆控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JtXtbSwu-1589477028346)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476723851.png)]
登陆逻辑:
private void button1_Click(object sender, EventArgs e)
{
if (!File.Exists("Log.txt"))//判断日志文件是否存在
{
File.Create("Log.txt");//创建日志文件
}
string strLog = "登录用户:" + textBox1.Text + " 登录时间:" + DateTime.Now;
if (textBox1.Text != "" && textBox2.Text != "")
{
using (StreamWriter sWriter = new StreamWriter("Log.txt", true))//创建StreamWriter对象
{
sWriter.WriteLine(strLog);//写入日志
}
Form1 frm = new Form1();//创建Form1窗体
this.Hide();//隐藏当前窗体
frm.Show();//显示Form1窗体
}
}
日志控件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xafampsC-1589477028348)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476715355.png)]
日志逻辑:
private void Form1_Load(object sender, EventArgs e)
{
StreamReader SReader = new StreamReader("Log.txt", Encoding.UTF8); //创建StreamReader对象
string strLine = string.Empty;
while ((strLine = SReader.ReadLine()) != null)//逐行读取日志文件
{
//获取单条日志信息
string[] strLogs = strLine.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
ListViewItem li = new ListViewItem();
li.SubItems.Clear();
li.SubItems[0].Text = strLogs[0].Substring(strLogs[0].IndexOf(':') + 1);//显示登录用户
li.SubItems.Add(strLogs[1].Substring(strLogs[1].IndexOf(':') + 1));//显示登录时间
listView1.Items.Add(li);
}
}
二进制流写入例子
控件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvJELKQ5-1589477028350)(C:\Users\biny\AppData\Roaming\Typora\typora-user-images\1589476811816.png)]
逻辑
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == string.Empty)//判断文本框是否为空
{
MessageBox.Show("要写入的文件内容不能为空");
}
else
{
saveFileDialog1.Filter = "二进制文件(*.dat)|*.dat";//设置保存文件的格式
if (saveFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件
{
//使用“另存为”对话框中输入的文件名实例化FileStream对象
FileStream myStream = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
//使用FileStream对象实例化BinaryWriter二进制写入流对象
BinaryWriter myWriter = new BinaryWriter(myStream);
myWriter.Write(textBox1.Text);//以二进制方式向创建的文件中写入内容
myWriter.Close();//关闭当前二进制写入流
myStream.Close();//关闭当前文件流
textBox1.Text = string.Empty;//清空文本框
}
}
}
private void button2_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "二进制文件(*.dat)|*.dat";//设置打开文件的格式
if (openFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件
{
textBox1.Text = string.Empty;//清空文本框
//使用“打开”对话框中选择的文件名实例化FileStream对象
FileStream myStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
//使用FileStream对象实例化BinaryReader二进制写入流对象
BinaryReader myReader = new BinaryReader(myStream);
if (myReader.PeekChar() != -1)//判断是否有数据
{
//以二进制方式读取文件中的内容
textBox1.Text = Convert.ToString(myReader.ReadInt32());
}
myReader.Close();//关闭当前二进制读取流
myStream.Close();//关闭当前文件流
}
}