可以移动到回收站的最长文件路径是多少?

8

对于我的应用程序,我正在测试可以移动到回收站的最长文件路径,并且我得到了有趣的结果。

在Windows XP上,最大大小为259个字符,这是MAX_PATH常量减1。

但是在我的Windows 8.1 Pro上,允许的最大文件路径大小似乎为215个字符。

所以我很好奇是否有任何官方指南?

编辑:好吧,由于下面的帖子要求API,我正在使用SHFileOperationFO_DELETE以及FOF_ALLOWUNDO将用户的文件放入回收站。由于Windows Explorer对其删除操作使用完全相同的API,因此可以通过在Windows Explorer中创建一个长路径,然后尝试删除该路径来轻松测试它。在我的实验中,我可以看到以下内容:

  • Windows XP中,如果总路径长度为259个字符(在某些版本中可能是257个字符),文件/文件夹将被放入回收站。否则,Windows资源管理器仅提供永久删除选项。

  • Windows Vista中,此限制为217个字符,包括在内。

  • Windows 7和8中,它是215个字符,包括在内。

因此,看起来这个最大限制正在缩小...因此我只是好奇,是否有文档记录在MSDN中?


1
@Spook:为什么?这是一个编程问题。 - c00000fd
2
嗯,大部分情况下它可能属于两者之一,尽管我不确定为什么用户真的会关心这个。对我来说,这绝对是一个编程问题(适合在这里提问)。而且还是一个好问题。+1 - MasterMastic
@c00000fd 不是的。这是关于Windows文件系统的问题,特别是NTFS。http://superuser.com/search?q=longest+file+path+windows - Spook
@HarryJohnston: 使用FO_DELETEFOF_ALLOWUNDOSHFileOperation。对于较长的文件路径,如果它们以\\.\开头,则是可以的,但Windows资源管理器和SHFileOperation不支持它。 - c00000fd
@c00000fd 请在问题中更新特定的API(以及测试用例代码和“有趣结果”的含义)。 - user2864740
显示剩余7条评论
2个回答

8

回收站内部:

Windows XP

每个驱动器都有自己的drive:\RECYCLER\%USER_SID%目录。该目录包含所有已删除的文件,但文件名为DcN.ext,其中D是名称固定部分,c是驱动器字母,N是索引,ext是原始文件的扩展名。除了已删除的文件外,还有一个名为INFO2的数据库文件。

INFO2文件以标题开头。标题结构如下:

Offset Type  Value
0x0000 DWORD Signature  ; Always 5
0x0004 DWORD Unknown1
0x0008 DWORD Unknown2
0x000C DWORD RecordSize ; Always 0x00000320
0x0010 DWORD Unknown3

记录紧随头文件存储,直到INFO2文件结束。记录结构如下:

Offset Type               Value
0x0000 ANSICHAR[MAX_PATH] OriginalFileNameA ; Ansi string
0x0104 DWORD              Index             ; Associated with *N* from *DcN.ext*
0x0108 DWORD              DriveIndex        ; A: = 0; B: = 1; C: = 2; ...
0x010C FILETIME           DeleteFileTime
0x0114 DWORD              OriginalFileNamePhysicalSize
0x0118 WIDECHAR[MAX_PATH] OriginalFileNameW ; Wide string

Windows Vista及以上版本

每个驱动器都有自己的drive:\$Recycle.Bin\%USER_SID%目录。该目录包含所有已删除的文件,但现在没有数据库文件。每个已删除的文件与RB内的2个文件相关联。

第一个文件的名称类似于$INNNNNN.ext,其中$I是名称的固定部分,NNNNNN由6个随机字母或数字组成,ext是原始文件的扩展名。

$I文件结构:

Offset Type               Value
0x0000 DWORD              Signature         ; Always 1
0x0004 DWORD              Unknown1
0x0008 DDWORD             OriginalFileSize
0x0010 FILETIME           DeleteFileTime
0x0018 WIDECHAR[MAX_PATH] OriginalFileNameW ; Wide string

第二个文件的名称类似于$RNNNNNN.ext,其中$R是名称的固定部分,NNNNNN与$I文件中相同,而ext是原始文件的扩展名。$R文件是被删除的文件本身。
正如您所看到的,在所有情况下,Windows将文件名存储在大小为MAX_PATH个字符的数组中。因此,文件名长度的限制为MAX_PATH-1个字符。 Windows 10 Windows 10具有新版本的$I文件结构(不知道哪个更新更改了它):
Offset Type                          Value
0x0000 DWORD                         Signature         ; Always 2
0x0004 DWORD                         Unknown1
0x0008 DDWORD                        OriginalFileSize
0x0010 FILETIME                      DeleteFileTime
0x0018 DWORD                         OriginalFileNameLen
0x001C WIDECHAR[OriginalFileNameLen] OriginalFileNameW ; Wide string

看起来现在Windows可以将任何路径下的文件存储到回收站中。

感谢提供信息。有了您的信息,我能够想出一个公式。我在这里描述了它:http://forums.codeguru.com/showthread.php?545395-How-can-I-get-path-to-the-recycle-bin-folder-for-a-specific-drive&p=2155927#post2155927 - c00000fd
不过有一个问题--回收站文件夹(这部分 C:\$Recycle.Bin)是否总是放置在驱动器的根目录下?换句话说,它不能是 C:\Something\$Recycle.Bin,对吗? - c00000fd
据我所知 - 总是在驱动器的根目录下。 - Denis Anisimov
2
有一个特殊情况,可能与之相关或不相关:如果用户的“文档”文件夹被重定向到网络(UNC)路径,则Windows会在“文档”文件夹下创建一个回收站文件夹。 - Harry Johnston
@HarryJohnston:说得好。谢谢。我刚刚测试了一下。发现任何重定向的文件夹(不仅仅是文档)都可以有自己的回收站。只要在客户端用户帐户中从该文件夹中删除了某些内容,它就会作为子文件夹在服务器上创建。服务器上的路径可能是这样的:C:\Home\UserName\Documents\$RECYCLE.BIN。请注意,从未重定向的文件夹中删除的内容会进入通用回收站或客户端机器上根文件夹中的回收站。嗯,这使事情变得复杂了,因为无法直接访问服务器上的 $RECYCLE.BIN - c00000fd
现在的问题是如何找出某个文件夹是否被重定向了? - c00000fd

0
简单的回答。回收站是一个(很好)隐藏在磁盘上的文件夹。其中所有的文件都保留着它们原来的名称,加上回收站文件夹名称的额外长度。
在Windows XP中,路径看起来像这样:
C:\RECYCLER\S-1-5-21-1089551744-1120685985-1162132538-1003\
我相信在后续版本中也是类似的,但可能会变得更长。您的文件名必须放在其末尾,并仍然保持在260个字符的限制内。

那么你如何找到特定系统的名称呢?尝试使用GetFinalPathnameByHandle,或者查看这篇博客。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364962.aspx

http://pdh11.blogspot.com.au/2009/05/pathcanonicalize-versus-what-it-says-on.html


更多有用的查找位置。

IKnownFolder: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776912.aspx

SHGetKnownFolderPath: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188%28v=vs.85%29.aspx

使用 CSIDL 的 SHGetFolderPath:http://msdn.microsoft.com/en-us/library/windows/desktop/bb762181%28v=vs.85%29.aspx


哈,有趣。谢谢你的回复。现在我明白了。只是好奇是否有任何API可以获取你引用的路径? - c00000fd
@IInspectable:是的,我知道。问题是如何获取特定驱动器(例如C:)的回收站路径? - c00000fd
@david.pfx,抱歉,我不明白你的逻辑。你能给个例子吗?显然,使用GetFinalPathnameByHandle需要一个回收站文件的句柄,对吧? - c00000fd
@david.pfx:我还是不太明白你的意思,抱歉啊,伙计。针对这个问题,我该使用哪个API呢:“您可以使用已知的文件夹ID来打开文件或文件夹,从而获得一个句柄”? - c00000fd
FOLDERID_RecycleBinFolder 表示不止一个物理文件夹。一个简单的情况是回收站对于每个 Windows 用户都是特定的。因此,文件系统 HANDLE 和 Shell 的回收站 CSIDL 之间绝对没有关联。 - c00000fd
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接