使用 .NET 进行文件备份的最佳方法
The best approach for file backup using .NET
文件备份应用程序有多种可能的解决方案。我需要知道哪种方法是可靠和专业的方式来执行数据文件的复制,即使文件正在使用或非常大。
有一种称为卷影复制 (VSS) 的已知方法,但我读到它对于简单的复制操作来说有点矫枉过正,因此可以使用 PInvoke BackupRead。
.NET 框架提供了它自己的方法:
File.Copy
与 large files and sharing the resources
曾经(可能仍然)存在问题
FileStream
似乎适合备份用途,但我没有找到全面的描述,我不确定我是否正确。
你能告诉我应该使用哪种方法吗(也许我忽略了一些选项)以及为什么?如果首选 VSS 或 PInvoke 方法,您能否也提供一个如何使用它的示例或对综合文档的一些参考(特别是我对创建文件句柄的正确设置感兴趣,这将允许在文件被访问时共享资源使用中)。
提前致谢。
您将在实时(即当前 运行ning OS)卷中尝试的所有内容都将无法打开某些文件。原因是,应用程序和 OS 本身以独占方式打开文件 - 也就是说,它们以 ShareMode=0 打开文件。您将无法阅读这些文件。
VSS 与支持 VSS 的应用程序协商以在持续时间内释放其打开的文件,但 Microsoft 以外的应用程序相对较少支持 VSS。
另一种方法是启动到另一个 OS(在 U 盘或另一个磁盘卷上)并从那里开始工作。例如,您可以使用 Microsoft 预安装环境 (WinPE)。您可以通过一些努力 运行 从那里创建 .Net 4.x 应用程序。在这样的环境中,您几乎可以访问目标卷上的任何文件而不会出现共享冲突。
WinPE 运行s 作为本地管理员。因此,您需要声明权限,例如 SE_BACKUP_NAME、SE_RESTORE_NAME、SE_SECURITY_NAME、SE_TAKE_OWNERSHIP_NAME,并且您需要使用名为 [=34= 的标志打开文件]...如所述here.
BackupRead/BackupWrite API 是有效的,尽管有点笨拙。您不能将异步文件句柄与这些 API 一起使用……或者至少 MS 声称如果您这样做,您将处于 "subtle errors" 状态。如果这些 API 过于复杂,您可以只使用 FileStreams。
这两种方式都有很多小问题。例如,您应该知道什么时候有硬链接在起作用,或者您将备份冗余数据……并且当您恢复时,您不想破坏这些链接。有一些 API 可以获取给定文件的所有硬链接...例如 NtQueryInformationFile。
ReparsePoints(Junctions 和 SymLinks)也需要特殊处理...因为它们是低级重定向到其他文件位置。一不小心就会运行跟着这些重解析点转圈,甚至会发现自己不小心备份了卷外数据。
处理所有这些东西并不容易,但如果彻底性是个问题,你会在完成之前遇到它们。
文件备份应用程序有多种可能的解决方案。我需要知道哪种方法是可靠和专业的方式来执行数据文件的复制,即使文件正在使用或非常大。
有一种称为卷影复制 (VSS) 的已知方法,但我读到它对于简单的复制操作来说有点矫枉过正,因此可以使用 PInvoke BackupRead。
.NET 框架提供了它自己的方法:
File.Copy
与 large files and sharing the resources
曾经(可能仍然)存在问题
FileStream
似乎适合备份用途,但我没有找到全面的描述,我不确定我是否正确。
你能告诉我应该使用哪种方法吗(也许我忽略了一些选项)以及为什么?如果首选 VSS 或 PInvoke 方法,您能否也提供一个如何使用它的示例或对综合文档的一些参考(特别是我对创建文件句柄的正确设置感兴趣,这将允许在文件被访问时共享资源使用中)。
提前致谢。
您将在实时(即当前 运行ning OS)卷中尝试的所有内容都将无法打开某些文件。原因是,应用程序和 OS 本身以独占方式打开文件 - 也就是说,它们以 ShareMode=0 打开文件。您将无法阅读这些文件。
VSS 与支持 VSS 的应用程序协商以在持续时间内释放其打开的文件,但 Microsoft 以外的应用程序相对较少支持 VSS。
另一种方法是启动到另一个 OS(在 U 盘或另一个磁盘卷上)并从那里开始工作。例如,您可以使用 Microsoft 预安装环境 (WinPE)。您可以通过一些努力 运行 从那里创建 .Net 4.x 应用程序。在这样的环境中,您几乎可以访问目标卷上的任何文件而不会出现共享冲突。
WinPE 运行s 作为本地管理员。因此,您需要声明权限,例如 SE_BACKUP_NAME、SE_RESTORE_NAME、SE_SECURITY_NAME、SE_TAKE_OWNERSHIP_NAME,并且您需要使用名为 [=34= 的标志打开文件]...如所述here.
BackupRead/BackupWrite API 是有效的,尽管有点笨拙。您不能将异步文件句柄与这些 API 一起使用……或者至少 MS 声称如果您这样做,您将处于 "subtle errors" 状态。如果这些 API 过于复杂,您可以只使用 FileStreams。
这两种方式都有很多小问题。例如,您应该知道什么时候有硬链接在起作用,或者您将备份冗余数据……并且当您恢复时,您不想破坏这些链接。有一些 API 可以获取给定文件的所有硬链接...例如 NtQueryInformationFile。
ReparsePoints(Junctions 和 SymLinks)也需要特殊处理...因为它们是低级重定向到其他文件位置。一不小心就会运行跟着这些重解析点转圈,甚至会发现自己不小心备份了卷外数据。
处理所有这些东西并不容易,但如果彻底性是个问题,你会在完成之前遇到它们。