異次元論壇

 找回密码
 中文注册

QQ登录

只需一步,快速开始

查看: 3366|回复: 8

[转载] Windows 下也能创建硬链接和符号(软)链接

[复制链接]
  • 2017-7-6 00:43 无聊
    已签167 天
    连签1 天
    [LV.7]常住居民III
  • 发表于 2014-6-3 23:52 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?中文注册

    x
    首先简单理解一下硬链接和符号(软)链接的区别(此文中的符号链接和软链接指同一概念):

    硬连接指向的是节点(inode),而软连接指向的是路径(path) 。

    最初的文件名与所有的硬链接地位是对等的,比如为文件 a 建立了硬链接 b、c、d。那么a、b、c、d之中只要有一个文件未删除,这个文件就可通未删除的名称访问的。你也可以认为每个文件都可认为至少有一个硬链接,就是说 a 也是一个硬链接。

    软链接特性上有些类似于快捷方式,比如为原文件 a 建立了软链接 b、c、d。删除b、c 或 d 访问到 a,但是只要删除了 a,软链接就不可用了。但是 windows 下的快捷方式只能在资源管理器中有用,它只是一个 lnk 文件,如果是一个目录的快捷方式,它是不能通过 cd 命令或路径进入。

    硬链接文件有两个限制(Unix/Linux 和 Windows 也都如此)
      1、不允许给目录创建硬链接;
      2、只有在同一文件系统中的文件之间才能创建链接。

    更详细区别请见:硬链结和符号链接的区别 ,具体不多述,本文的内容关键在 Windows 下如何建立软硬链接。

    熟悉过 Unix/Linux 都应该知道,Unix/Linux 用 ln 建立硬链接,ln -s 建立软链接,那么 Windows 下是如何做到的呢?

    一: Windows 下创建硬链接,只能适用于 NTFS 文件系统。使用命令 fsutil hardlink
    语法
    fsutil hardlink create NewFileName ExistingFileName
    参数
    create 建立现有文件和新文件之间的 NTFS 硬链接。NTFS 硬链接与 POSIX 硬链接相似。
    NewFileName 指定要将创建硬链接的文件。
    ExistingFileName 指定要从中创建硬链接的文件。

    当然,如果你想在自己的程序里创建硬链接,那也是很容易的,只需要一个很简单的 API 函数:
    BOOL CreateHardLink(
       LPCTSTR lpFileName,
       LPCTSTR lpExistingFileName,
       LPSECURITY_ATTRIBUTES lpSecurityAttributes
    );
    适用于 Win2000 及以上版本的系统,前两个参数的意思就不用解释了,最后一个参数的用途暂时保留,必须为 NULL。

    二:Windows 下创建软链接,NTFS 只支持对目录的软链接,微软把它称作 junction。但是对于文件的软链接,微软也有提供解决方案,那就是快捷方式(Shortcut,.lnk 文件)。不过软链接和快捷方式不是一个层次上的东西,前者是底层文件系统的功能,后者是应用层的功能。Windows 下目录的快捷方式用 dir 看起来是个文件。

    在 https://www.microsoft.com/technet/sysinternals/FileAndDisk/Junction.mspx 下载 junction.exe。junction 的命令语是:

    junction  LinkDirectory ExistingDirectory

    例如:junction d:\link c:\winnt

    将为c:\winnt 建立一个链接目录 d:\link,C和D分区都要是 NTFS 格式,在资源管理器和 dir 列示中 d:\link 都以目录的面目存在的。d:\link 就像是 c:\winnt 的一个引用一般,删除 d:\link 目录中的内容也就是删除了 c:\winnt 中的内容,但删除 d:\link 本身是不会影响到 c:\winnt 的。

    相应的,在程序中也有一个 API 函数 CreateSymbolicLink 支持创建软链接,不过来得太晚了,要 Windows VISTA 和 Windows Server 2008 那样的版本才支持,先还是别想了,API 原型是:

    BOOL WINAPI CreateSymbolicLink(
    __in  LPCWSTR lpSymlinkFileName,
    __in  LPCWSTR lpTargetFileName,
    __in  DWORD dwFlags
    );
    参数:
    lpSymlinkFileName 要创建的符号链接名称.
    lpTargetFileName 符号链接所对应目标的名称.
    dwFlags 标识目标是文件还是目录. 取值0x0 代表是文件,SYMBOLIC_LINK_FLAG_DIRECTORY或0x1 代表是目录

    三:其他方法

    也可以使用 GNU utilities for Win32 中的 ln 来创建硬链接。这是一些 GNU 工具的 Win32 移植版本,非常好用。另外 Cygwin 里的 ln 不但可以创建硬链接也可以创建符号链接(在 Windows 里就是快捷方式 .lnk 文件)。
    实际需求引出:Web 应用中上传文到 WEB 下的某个子目录中,这样可以直接通过网页链接的方式访问到这些文件。但是会出现的问题就是,每当完全重新部署应用时,如果忘了把存上传文件的目录进行备份,那么原有上传文件就全没了。原来项目部署在 Unix 下的做法是,把那个上传目录作为另一个目录的符号链接,实际存储文件的目录不在 WEB 应用目录下,重新部署时只要重建这个符号链接即可,不会有覆盖文件的危险。当然在 Unix/Linux 是好解决,只要用 ln -s 命令就行,然而对于 Windows 系统却要想点办法,为目录建立快捷的方式是行不通的,目录的链接只会当 lnk 文件对待,在 Explorer 中可以双击打开,但对于网页链接或者 cd 命令是无法正确定位的。于是思考起如何在 Windows 下创建符号连接的问题,才有了上文。

    题外:对于以上的需求,可以在 Web 应用外部事先建立好一个目录,赋上相应的权限。然后在应用的配置文件中记下这个目录的绝对路径,上传时往其中写文件没问题,关键浏览时,因为文件在应用之后,不能直接通过网址浏览到,就需要通过一个程序去读取相应的文件,发送到浏览器之前必须设置根据文件类型设置响应 MINE 类型,这个 MINE 类型可以在上传时记载在库的。

    现在觉得这种方法还优于用符号链接的方式,至为无需每次完整发布后重创建符号链接,而且实际中也出现过完全重部署后,目标目录中文件完全丢失的情况。

    参考:1. NTFS 下的硬链接(hard link)与符号链接(symbolic link)
           2. 原来Windows下面也有硬链接       3. Windows上创建硬链接
           4. MSDN CreateSymbolicLink Function
           5. MSDN CreateHardLink Function
           6. ln命令详细用法
    https://www.blogjava.net/Unmi/archive/2007/11/26/163055.html

    回复

    使用道具 举报

  • 2024-4-28 14:34 开心
    已签3500 天
    连签26 天
    [LV.Master]伴坛终老
  • 发表于 2014-6-4 00:03 | 显示全部楼层
    謝謝樓主分享技術.
    回复 支持 反对

    使用道具 举报

  • 2017-1-9 16:33 开心
    已签696 天
    连签1 天
    [LV.9]以坛为家II
  • 发表于 2014-6-4 08:01 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    头像被屏蔽
  • 2015-5-8 17:58 开心
    已签345 天
    连签8 天
    [LV.8]以坛为家I
  • 发表于 2014-6-4 09:40 | 显示全部楼层
    多谢分享
    回复 支持 反对

    使用道具 举报

  • 2016-2-29 08:06 开心
    已签1221 天
    连签1 天
    [LV.10]以坛为家III
  • 发表于 2014-6-4 17:02 | 显示全部楼层
    谢谢分享经验
    回复 支持 反对

    使用道具 举报

  • 2017-5-20 14:09 无聊
    已签143 天
    连签1 天
    [LV.7]常住居民III
  • 发表于 2014-6-4 19:08 | 显示全部楼层
    谢谢楼主分享
    回复 支持 反对

    使用道具 举报

  • 2017-10-4 15:49 开心
    已签564 天
    连签1 天
    [LV.9]以坛为家II
  • 发表于 2014-6-4 19:30 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

  • 2017-6-17 16:42 开心
    已签324 天
    连签1 天
    [LV.8]以坛为家I
  • 发表于 2014-6-7 09:43 | 显示全部楼层
    WINDOWS还有这功能,多谢楼主分享
    回复 支持 反对

    使用道具 举报

  • 2017-10-18 01:37 奋斗
    已签862 天
    连签1 天
    [LV.10]以坛为家III
  • 发表于 2014-10-24 22:13 | 显示全部楼层
    謝謝道友分享
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 中文注册

    本版积分规则

    GMT+8, 2024-4-29 02:36 , Processed in 0.260476 second(s), 23 queries .

    © 2010-2015 異次元論壇 Powered by Discuz! 手机版|Archiver|

    異次元論壇内容均由道友发表,不代表異次元立场,禁止在发表与国家法律相抵触言论!如侵犯了您的权利请发帖投诉。
    快速回复 返回顶部 返回列表