检测 File.Move 是否需要“复制 ->”删除或者只是更改文件系统表中的位置

发布于 2024-12-03 15:30:30 字数 1096 浏览 1 评论 0原文

免责声明: 我立即承认我对文件系统如何运作的细节有相当多的无知。我已经使用 NTFS 很长时间了,我可以根据我所目睹的行为以及我从互联网上学到的东西来推断正在发生的事情 - 然而......

我希望有一种方法可以检测到如果将文件从“位置 A”移动到“位置 B”时,该操作是否需要相当于“File.Copy ->” File.Delete'或者它不会复制实际的文件数据,而只是更新'主文件表'等中的位置。

出于各种目的,我有时会移动大量大文件。我喜欢在 UI 中报告进度。

我意识到,当我调用 File.Move 并将文件从一个磁盘/分区上的某个位置移动到另一个位置时,该函数实际上必须“复制文件数据 -> ”。磁盘/分区之间的“删除”。当遇到这种情况时,我希望能够检测到这种情况会发生,这样我就可以使用我编写的代码来复制文件并在字节传输时提供详细的进度报告,以便我可以经常更新 UI 中的进度条。

当它位于同一磁盘/分区上时,由于更新主文件表中的位置非常快,因此我只需在 file.Move 函数为我批量移动的每个文件完成时更新进度条。

使用 .NET 4 (C#),是否可以通过其他方式检测调用 File.Move 是否需要等效的“复制 ->”删除'操作还是只是更新文件表而不复制文件数据?

编辑:

正如我在下面的评论中指出的,我认为如何完成此操作的可能性是检测给定的源文件位置和目标文件位置是否位于相同的物理磁盘和分区,如果是这样,这是否意味着我可以准确地预测行为并决定调用哪些函数 - 用于“近乎即时”更新文件系统表的内置 File.Move 函数,我相信在移动到同一磁盘/部件时会发生这种情况,或者我更详细的“每复制‘x’个字节报告进度”自定义文件复制代码。文件传输速度在我的程序将运行的计算机上可能会有很大差异,因此我希望能够在可能的情况下报告详细进度/当前传输速度。

注意 - 程序可能使用网络 UNC 路径,该路径可以使用具有相同根路径的不同物理磁盘,即: \\somename\shares\workfolder\project 可能位于不同的物理磁盘上,然后 \\somename\shares\workfoldder\otherproject 。因此,我需要一种方法来检测分区 ID 或物理磁盘 ID,以查看源文件夹和目标文件夹是否位于同一磁盘/分区上。

谢谢

Disclaimer:
I will admit straight away I have a fair amount of ignorance regarding the details on how file systems function. I have been using NTFS for so long that I can extrapolate what is going on based on behaviors I have witnessed, as well as whatever I have learned from dorking on the internet - however...

I was hoping that there is a way to detect if when moving a file from 'location A' to 'location B', whether the operation will require the equivalent of 'File.Copy -> File.Delete' or if it will not copy the actual file data, but just update the location in the 'master file table' or the like.

For various purposes, I sometimes move large numbers of large files. I like to report progress in the UI.

I realize that when I call File.Move and move a file from a location on one disk/partition to another, that the function will effectively have to 'copy file data -> delete' between the disks / partitions. When it encounters this situation, I want to be able to detect that this will happen so I can use code I have authored that will copy the file and give detailed progress reporting as bytes are transferred so I can update progress bars in the UI frequently.

When it is on the same disk/partition, as updating the location in the master file table is so fast, I simply update the progress bar when the file.Move function completes for each file I am batch moving.

Using .NET 4 (C#), is it possible to detect through other means whether calling the File.Move will require an equivalent 'copy -> delete' operation or will simply update a file table and not copy the file data?

Edit:

As I note in comments below, possibilities on how I thought this might be done would be to detect if a given source file location and destination file location are located on the same physical disk & partition, and if so, would this mean I could accurately anticipate the behavior and decide what functions to call - the built in File.Move function for the 'near instant' update file system table that I believe occurs when moving to same disk/part, or my more detailed 'report progress every 'x' bytes copied' custom file copy code. File transfer speeds can vary greatly on the machines my programs will run on so I like to be able to report detailed progress / present transfer speed when possible.

Note - The program may be using network UNC paths which can be using different physical disks with the same root path i.e.: \\somename\shares\workfolder\project may be on a different physical disk then \\somename\shares\workfoldder\otherproject. So I would need a method for detecting the partition ID or physical disk ID to see if a source and destination folder on on the same disk/partition.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦太阳 2024-12-10 15:30:30

您始终可以 P/Invoke MoveFileWithProgress。从粗略的阅读来看,当文件被复制而不是移动时,它看起来会为您提供更精细的进度。

或者,总是有 SHFileOperation,将为您提供 Windows 资源管理器 UI 和语义。

You could always P/Invoke to MoveFileWithProgress. From a cursory reading, it looks like it'll give you more granular progress when a file is copied, rather than moved.

Alternatively, there's always SHFileOperation, which'll give you the Windows Explorer UI and semantics.

把昨日还给我 2024-12-10 15:30:30

我认为你无法以正常的方式检测到这样的事情,因为你不应该关心。如果您可以测试这一点,那么 if 和 else 情况会是什么,因为无法从中提取任何知识(除了传输速度)。

在 .net 中,文件系统是抽象的,因此您可以将文件从一个位置移动到另一个位置,而无需知道要从/复制到哪个分区/文件系统/网络驱动器。

对于您的具体问题,为什么不总是显示进度条并在这两种情况下以一定的时间间隔更新它。

I don't think you can detect such a thing in a normal way as you're not supposed to care. If you could test this, what would be the if and else case be as no knowledge can be extracted from this (except for the speed of the transfer).

In .net the file system is abstracted so you can just move files from one place to another without knowing what partition/filesystem/network drive you're copying from/to.

For your specific problem, why don't you always show the progressbar and have it updated at a certain interval for both cases.

药祭#氼 2024-12-10 15:30:30

我很确定你不能这样做。

对于初学者来说,即使在 NTFS 上,仅查看本地驱动器的驱动器盘符也是不够的,因为 您可以将驱动器安装到现有驱动器上的空文件夹内。这意味着即使两个路径具有相同的驱动器号,它们仍然可以安装在不同的磁盘上。

进一步考虑外部共享,可能是安装在基于 *nix 的系统上并通过 Samba 公开的共享。 *nix 符号链接使得无法仅通过查看路径来判断两个路径是否驻留在同一物理设备上 - 唯一的选择是查询远程计算机“这两个路径是否存在于同一驱动器上?”我非常怀疑会不会暴露。

我只会使用 File.Move 并接受您不会收到进度更新的事实。无论如何,编写自己的副本实现让我觉得“不是一个特别好的主意”。

I'm pretty sure that you can't do this.

For starters even on NTFS just looking at the drive letter for local drives isn't enough because you can mount a drive inside an empty folder on an existing drive. This means that even if the two paths have the same drive letter they could still be mounted on different disks.

To take it another step further consider external shares, possibly ones mounted on an *nix based system and exposed via Samba. *nix symbolic links make it impossible to tell whether two paths reside on the same physical device by looking at paths alone - the only option have would be to query the remote machine "do these two paths exist on the same drive?", something which I very much doubt would be exposed.

I would just use File.Move and accept that you don't get progress updates. Writing your own copy implementation strikes me as a "not a particularly good idea" anyway.

爺獨霸怡葒院 2024-12-10 15:30:30

虽然不是 100% 正确(符号链接使它看起来像是一个大分区,但它们可能是不同的物理驱动器(从我的头顶开始,就像 WHS 广泛使用的那样),但我想说的是,为了进度条的目的,假设保持在同一分区(System.IO.Path.GetPathRoot)上,可能就足够了。

While not 100% correct (sym-links make it look like things are one big partition while they may be different physical drives (from the top of my head like WHS uses extensivly), I would say for the purpose of progress bar assuming that staying on the same partition (System.IO.Path.GetPathRoot), will probably be enough.

街角卖回忆 2024-12-10 15:30:30

我对监控传输速度和进度条一无所知,但对于检测文件是否正在移动到不同驱动器/分区的问题,您只需比较目标和源文件的驱动器/分区号...

如果您正在使用 File.Move 的完整路径,您可以使用像这样简单的东西:

if(sourcePath[0]!=destinationPath[0])
    //enable transfer speed monitoring

如果您使用相对路径,您需要使用更多的字符串路径解释来提取目标/源驱动器/分区。

如果我的解决方案太简单或者我没有看到其他问题,我很抱歉。

I don't know anything about monitoring transfer speed and progress bars but for the issue of detecting if a file is being move to a diffrent drive/partition you could just compare the drive/partition letter of the destination and source file...

if you are using full paths for File.Move you could use something as simple as:

if(sourcePath[0]!=destinationPath[0])
    //enable transfer speed monitoring

if you are using relative paths you need to extract the destination/source drive/partition with a little more string path interpreting.

I'm sorry if my solution is too simple or if I'm not seeing some other problem.

那支青花 2024-12-10 15:30:30

您可以 P/调用 GetFileInformationByHandle() 函数,该函数返回卷序列号。如果两个文件的卷序列号相同,则它们位于同一卷上,无需复制和删除。

You can P/Invoke the GetFileInformationByHandle() function, which returns the volume serial number. If the volume serial number is the same for both files, they are on the same volume and no copy-and-delete will be necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文