前言
官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/file-system/
官方文档写的真心不错。
常用路径
系统特殊文件夹的目录路径
系统路径
我的文档
1 | string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); |
桌面
1 | string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); |
数据目录
1 | string ApplicationData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); |
图片
1 | string picPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); |
程序所在文件夹
exe文件所在的目录(不包含xxx.exe)
方法1:
1 | //获取和设置当前目录(即该进程从中启动的目录)的完全限定路径。 |
方法2:
1 | //获取当前 Thread 的当前应用程序域的基目录,它由程序集冲突解决程序用来探测程序集。 |
方法3:
1 | //获取和设置包含该应用程序的目录的名称。 |
方法4:
1 | //获取启动了应用程序的可执行文件的路径,不包括可执行文件的名称。 |
方法5:
1 | //获取应用程序的当前工作目录(不可靠)。 |
EXE路径
X:\xxx\xxx\xxx.exe (.exe文件所在的目录+.exe文件名)
方式1
1 | string starupPath = GetType().Assembly.Location; |
方式2
1 | string starupPath2 = Process.GetCurrentProcess().MainModule.FileName; |
方式3
获取启动了应用程序的可执行文件的路径,包括可执行文件的名称。
1 | string str = System.Windows.Forms.Application.ExecutablePath; |
Download路径
Windows没有为下载
文件夹定义CSIDL.aspx),并且通过Environment.SpecialFolder
枚举无法使用它。
1 | public static class KnownFolder |
路径拼接
1 | Path.Combine(ZConfig.basePath, "images") |
注意
这样路径拼接后类似于
E:\project\schoolclient\bin\x86\Debug\images
,没有最后的反斜杠参数可以多个,类型必须为字符串
另外一定要注意
参与拼接的路径不要以
\
或者/
开始,这样返回的路径不是拼接的路径。
比如
1 | Path.Combine("D:/test/", "/images/1.png"); |
我们获取到的结果是/images/1.png
,而不是D:/test/images/1.png
。
这样才是正确的
1 | Path.Combine("D:/test/", "images/1.png"); |
分隔符
在 Windows 上,反斜杠 \
被广泛地用作路径分隔符,例如 C:\Users\username\Documents
。
Path相关方法返回的路径的分隔符也是\
。
在 Linux 和 macOS 等基于 Unix 的操作系统上,正斜杠 /
被用作路径分隔符,例如 /home/username/Documents
。
C#中有两个分隔符
Path.DirectorySeparatorChar
对应的是\
Path.AltDirectorySeparatorChar
对应的是/
这两个分隔符在Windows上都是支持的,即使一个路径中两种分隔符都存在也没有问题。
但是在Linux上只支持/
,为了兼容我们可以把路径分割符进行替换
1 | filepath = filepath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); |
这样可以确保路径格式在不同操作系统上都是正确的。
如果程序只运行在Windows上,则不用替换分隔符。
需要注意的是,在使用 Path.DirectorySeparatorChar
或 Path.AltDirectorySeparatorChar
时,应该尽量避免手动拼接路径字符串,而是使用 Path.Combine()
方法来完成路径拼接,以保证路径在不同操作系统下都能正确处理。
文件夹
获取并创建项目文件夹
项目中可以写一个通用的获取文件夹的方法
1 | public static string GetBaseFolder(params string[] pathParas) |
使用
获取项目的根目录
1 | string projectBaseFolder = ZImgUtils.GetBaseFolder(); |
或者多个子级
1 | string projectBaseFolder = ZImgUtils.GetBaseFolder("imgs", "source"); |
创建文件夹
创建文件夹的方法要注意以下两点:
- 创建文件夹时候是能直接创建多层的,不用一层一层创建。
- 创建文件夹可以不判断之前存在不存在,直接调用不会报错也不会删除之前文件夹下的文件。
方式1
1 | var dirPath = ZConfig.cacheImagePath; |
方式2
1 | string savePath = |
获取文件所在文件夹
获取父文件夹
1 | string filePath = @"C:\path\to\file.txt"; |
创建父文件夹
1 | FileInfo fi = new FileInfo(filepath); |
删除文件夹
1 | DirectoryInfo tongpingPath = new DirectoryInfo(ZConfig.classTongpingPath()); |
也可以
1 | if (Directory.Exists(tempPath)) |
其中
Delete(true)会自动删除子文件夹。
删除文件夹前一定要判断文件夹是否存在,否则会异常。
获取文件夹下文件
只获取下一层的文件
方式1
1 | string[] files = Directory.GetFiles(path, "*.txt"); |
方式2
1 | DirectoryInfo folder = new DirectoryInfo(path); |
所有目录和文件名
递归地输出当前运行程序所在的磁盘下的所有文件名和子目录名
1 | static void Main(string[] args) |
获取文件名
c#根据绝对路径获取 带后缀文件名、后缀名、文件名。
1 | string str =" E:\test\Default.aspx"; |
2、c#根据绝对路径获取 带后缀文件名、后缀名、文件名,使用 Split 函数。
1 | string str = =" E:\test\Default.aspx"; |
3、C# 获取文件名及扩展名
1 | string aFirstName = aFile.Substring(aFile.LastIndexOf("\\") + 1, (aFile.LastIndexOf(".") - aFile.LastIndexOf("\\") - 1)); //文件名 |
还有的就是用Substring截取
1 | strFilePaht.Substring(path.LastIndexOf("\\") + 1, path.Length - 1 - path.LastIndexOf("\\")); |
或者用openFileDialog1.SafeFileName
这样就能取到该文件的所在目录路径
1 | string path1 = System.IO.Path.GetDirectoryName(openFileDialog1.FileName) + @"\"; |
文件
判断文件是否占用
方式1
1 | /// <summary> |
方式2(推荐)
推荐使用这种方式 控制台不会报错
1 | [ ] |
文件删除
1 | //删除文件 |
文件复制
1 | if (File.Exists(SavePath)) |
文件移动/重命名
1 | FileInfo fi = new FileInfo(TempVideoPathName); |
或者
1 | if (File.Exists(SavePath)) |
生成新文件路径
1 | using System; |
覆盖写入
1 | using System.IO; |
同步
1 | File.WriteAllText(filePath, content); |
追加写入
1 | using System.IO; |
同步
1 | File.AppendAllText(filePath, content); |
读取文本文件
1 | int counter = 0; |
异常
以下情况可能会导致异常:
- InvalidOperationException:文件已存在并且为只读。
- PathTooLongException:路径名可能太长。
- IOException:磁盘可能已满。
使用文件系统时,还有其他可能会导致异常的情况,因此最好进行防御性编程。
获取屏幕二进制
1 | public static byte[] CaptureScreen() |
保存屏幕截图到文件
1 | private static int iw = Screen.PrimaryScreen.Bounds.Width; |
注意
这真是个大坑,上面的截屏并保存文件的代码明明该释放的都释放了,但是循环执行的时候内存还是会一直增长,反复实验发现,Bitmap调用Save方法后,内存并不会释放,只要我们在生成图片文件的同时延迟删除生成的图片内存就不会增长了,真是迷了!!!
延迟删除图片
1 | private static void deleteFile(string filepath) |
保存图片
获取图片
1 | using System; |
保存图片
1 | Bitmap img = ZScreenUtil.CaptureScreen(); |
保存图片并压缩
1 | public static string CaptureScreenSave(string filePath) |
保存二进制到文件
1 | using (Stream fls = new FileStream(filePath, FileMode.Create)) |
文件夹/文件复制移动
循环访问目录树
如果你确信拥有指定根目录下的所有目录的访问权限,则可以使用 System.IO.SearchOption.AllDirectories
标志。 此标志返回与指定的模式匹配的所有嵌套的子目录。
1 | root.GetDirectories("*.*", System.IO.SearchOption.AllDirectories); |
此方法的缺点是,如果指定根目录下的任何子目录引发 DirectoryNotFoundException 或 UnauthorizedAccessException 异常,则整个方法失败且不返回任何目录。 使用 GetFiles 方法时也是如此。 如果需要处理特定子文件夹中的异常,则必须手动遍历目录树,如以下示例所示。
手动遍历目录树时,可以先处理文件(前序遍历),或者先处理子目录(后序遍历)。 如果执行前序遍历,则可直接访问该文件夹本身下的文件,然后遍历当前文件夹下的整个树。 后序遍历是另一种方法,在访问当前文件夹的文件之前遍历下面的整个树。 本文档后面的示例执行的是前序遍历,但你可以轻松地修改它们以执行后序遍历。
获取目录下所有文件
1 | root.GetFiles("*.*"); |
另一种选择是,是使用递归遍历还是基于堆栈的遍历。
本文档后面的示例演示了这两种方法
下面的示例演示如何以递归方式遍历目录树。
递归方法是一种很好的方法,但是如果目录树较大且嵌套深度较深,则可能引起堆栈溢出异常。
在每个文件或文件夹上处理的特定异常和执行的特定操作仅作为示例提供。
1 | public class RecursiveFileSearch |
下面的示例演示如何不使用递归方式遍历目录树中的文件和文件夹。
此方法使用泛型 Stack 集合类型,此集合类型是一个后进先出 (LIFO) 堆栈。
1 | public class StackBasedIteration |
通常,检测每个文件夹以确定应用程序是否有权限打开它是一个很费时的过程。 因此,此代码示例只将此部分操作封装在 try/catch
块中。 你可以修改 catch
块,以便在拒绝访问某个文件夹时,可以尝试提升权限,然后再次访问此文件夹。 一般来说,仅捕获可以处理的、不会将应用程序置于未知状态的异常。
如果必须在内存或磁盘上存储目录树的内容,那么最佳选择是仅存储每个文件的 FullName 属性(类型为 string
)。 然后可以根据需要使用此字符串创建新的 FileInfo 或 DirectoryInfo 对象,或打开需要进行其他处理的任何文件。
复制文件和目录
1 | // Simple synchronous file copy operations with no user interface. |
移动文件和目录
1 | // Simple synchronous file move operations with no user interface. |
删除文件和目录
1 | // Simple synchronous file deletion operations with no user interface. |
选择文件
WPF中,调用OpenFileDialog时有两个选择:
- System.Windows.Forms.OpenFileDialog
- Microsoft.Win32.OpenFileDialog
方式1
1 | System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog(); |
方式2(推荐)
选择图片
1 | Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); |
过滤具体文件
1 | Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog |
图片多选
1 | string picPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); |
选择文件夹
1 | System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog(); |