符号链接、硬链接、快捷方式和Junctions
UNIX系统支持符号链接和硬链接,也许大多数人都是在学习UNIX时第一次接触这两个概念的。DOS当初过于简单,自然也不支持类似的概念。到了 Windows的年代,产生了广为使用的快捷方式。到Windows NT的时候,微软逐步加入了对硬链接的支持。当然Windows中的实现还是不完全和UNIX一致。
1、UNIX中的符号链接(Symbolic links),可以链接目录或文件、可以跨文件系统。创建符号链接时,不会增加目标文件的引用计数。删除目标文件时,符号链接仍然存在,当然在使用它的时候会发现失效了。
我们在Linux下做个实验:
$ touch foo
$ ls -l foo
-rw-rw-r– 1 uniware uniware 0 Mar 8 15:26 foo
$ ln -s foo foo1
$ ls -l foo*
-rw-rw-r– 1 uniware uniware 0 Mar 8 15:26 foo
lrwxrwxrwx 1 uniware uniware 3 Mar 8 15:27 foo1 -> foo
$ ln -s foo1 foo1_1
$ ls -l foo*
-rw-rw-r– 2 uniware uniware 0 Mar 8 15:26 foo
lrwxrwxrwx 1 uniware uniware 3 Mar 8 15:27 foo1 -> foo
lrwxrwxrwx 1 uniware uniware 4 Mar 10 13:04 foo1_1 -> foo1
$ mkdir bar
$ ls -ld bar
drwxrwxr-x 2 uniware uniware 4096 Mar 8 15:28 bar
$ ls -ld bar*
drwxrwxr-x 2 uniware uniware 4096 Mar 8 15:28 bar
lrwxrwxrwx 1 uniware uniware 3 Mar 8 15:29 bar1 -> bar
2、UNIX中的硬链接(Hard links),只能链接文件、不能链接目录,而且不能跨文件系统。创建链接时,将增加目标文件的引用计数。删除目标文件或链接文件时都会导致引用计数减少。
$ ln foo foo2
$ ls -l foo*
-rw-rw-r– 2 uniware uniware 0 Mar 8 15:26 foo
lrwxrwxrwx 1 uniware uniware 3 Mar 8 15:27 foo1 -> foo
-rw-rw-r– 2 uniware uniware 0 Mar 8 15:26 foo2
$ ln foo foo2_2
$ ls -l foo*
-rw-rw-r– 3 uniware uniware 0 Mar 8 15:26 foo
-rw-rw-r– 3 uniware uniware 0 Mar 8 15:26 foo2
-rw-rw-r– 3 uniware uniware 0 Mar 8 15:26 foo2_2
$ ln bar bar2
ln: `bar’: hard link not allowed for directory
3、Windows中的硬链接(Hard links),只能链接文件、不能链接目录,而且不能跨文件系统。创建链接时,也会增加目标文件的引用计数(MSDN说最大可创建的硬链接数为 1023)。这个和UNIX的硬链接类似。不过只能在NTFS文件系统中使用。创建硬链接的API为CreateHardLink()。
请看测试程序:
/* CreateHardLink() is supported for version >= 0x500 */
#define _WIN32_WINNT 0x500
/* defined for UNICODE version */
#define UNICODE
#define _UNICODE
#include
int _tmain(void)
{
HANDLE hFile;
BOOL fCreatedLink;
TCHAR pszNewLinkName[MAX_PATH];
TCHAR pszExistingFileName[MAX_PATH];
INT i = 0;
_tcscpy(pszExistingFileName, _T(“foo.dat”));
hFile = CreateFile(pszExistingFileName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
_tprintf(_T(“CreateFile(): %d\n”), GetLastError());
exit(1);
}
CloseHandle(hFile);
for ( ; ; )
{
_stprintf(pszNewLinkName, _T(“foo_link%d”), i);
fCreatedLink = CreateHardLink(pszNewLinkName,
pszExistingFileName,
NULL);
if (!fCreatedLink)
{
_tprintf(_T(“GetLastError(): %d\n”), GetLastError());
break;
}
i++;
}
_tprintf(_T(“Number of hard links: %d\n”), i);
getchar();
exit(0);
}
正常运行后的结果应该是:
GetLastError(): 1142
Number of hard links: 1023
其中错误号1142的含义是“试图在文件上创建超过文件系统支持的链接数。”。
4、Windows中的快捷方式(Shortcuts),可以指向文件或目录,也可以跨文件系统。符号链接仍然存在,当然在使用它的时候会发现失效了。它非常类似于UNIX的符号链接。
5、Windows中还有一个特殊的东西:Junctions。它只能指向目录,也可以跨本机的文件系统,但不能跨网络文件系统。它类似于UNIX下的Mount。不过也只能在NTFS文件系统中使用。MSDN的知识库文章 “How to Create and Manipulate NTFS Junction Points” 说明了如何用工具操纵Junctions,不过要在程序中使用Junctions,还是非常麻烦。这里有个很好的例子: Reparse points and junctions 。
不管是符号链接、硬链接,还是Junctions、Mount,都会给用户带来一定程序的方便,也会给我们带来很多意想不到的麻烦。比如说,很多时候我们 都需要遍历一个目录,并对遇到的目录或文件做些操作。有时我们是在遍历时修改文件的属性,有时是修改它的名字,有时是想改变其内容,还有的时候我们需要计 算文件/目录的大小。符号链接、硬链接等概念会可能我们的操作带来不尽的烦恼。 “Computing the size of a directory is more than just adding file sizes” 还指出了更多需要注意的问题。
Copyright 2000-2006,zedware_at_gmail_dot_com
Last modified on Thursday, 2006-05-18
File System
]