倾听王菲网站关闭的通知
作者:青锋幽灵 日期:2008-11-29 15:31
Windows 下也能创建硬链接和符号(软)链接
作者:青锋幽灵 日期:2010-01-24 22:50
首先简单理解一下硬链接和符号(软)链接的区别(此文中的符号链接和软链接指同一概念):
硬连接指向的是节点(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 看起来是个文件。
在 http://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命令详细用法
有固定宽度页面的背景广告JS代码
作者:青锋幽灵 日期:2009-07-06 15:37
以下是已经封装的JS类,点击这里查看效果。
- /*
- Powered By CMSDream Copyright © All rights reserved.
- */
- var backgroundAd = {
- Div: null,
- IE: 10, /*IE版本*/
- CD: new Array(1),
- AD: new Array(1),
- Config: {
- adTime: {
- begin: "2009/7/15 00:00:00", /*开始时间*/
- end: "2009/7/16 23:59:59" /*结束时间*/
- },
- Type: 0, /*0-IE6 背景固定 不等于0-IE6背景浮动*/
- minWidth: 930, /*页面最小宽度*/
- totalWidth: 0,
- adWidth: 283, /*广告宽度*/
- adImage:{
- left: 'l.gif',
- right: 'r.gif'
- },
- adURL: 'http://get.766.com/go.php?id=2303', /*广告连接地址*/
- adClick: 0, /*是否允许点击*/
- bgImage: 'bg.jpg', /*广告背景图片*/
- bgColor: '#6EE6FE', /*广告背景颜色*/
- oldBackground: '', /*页面原背景*/
- /*关闭按钮*/
- closeImage: {
- src: 'close.jpg',
- width: 13,
- height: 13
- }
- },
- createAd: function(u){
- var self = this;
- var h = document.body.clientHeight;
- var div = document.createElement('div');
- with(div.style){
- if(this.Config.adClick){
- cursor = 'pointer';
- }
- position = 'absolute';
- width = this.Config.adWidth + 'px';
- height = h + 'px';
- backgroundImage = "url(" + this.Config.adImage[u] + ")";
- backgroundRepeat = 'no-repeat';
- backgroundPosition = u + ' 0';
- backgroundAttachment = 'fixed';
- top = 0;
- zIndex = 0;
- eval(u + ' = '' + (-this.Config.adWidth) + 'px'');
- }
- if(this.Config.adClick){
- div.onclick = function(){
- window.open(self.Config.adURL, '_blank');
- };
- }
- return div;
- },
- createClose: function(u){
- var self = this;
- var a = document.createElement('a');
- a.href = '#close';
- with(a.style){
- position = 'absolute';
- width = self.Config.closeImage.width + 'px';
- height = self.Config.closeImage.height + 'px';
- top = 0;
- zIndex = 0;
- eval(u + ' = '' + (-this.Config.adWidth) + 'px'');
- }
- a.onclick = function(){
- var pp = self.Div.parentNode;
- pp.removeChild(self.Div);
- if(self.Config.oldBackground.length > 0)
- document.body.style.background = self.Config.oldBackground;
- return false;
- };
- a.innerHTML = '<img src="'+this.Config.closeImage.src+'" '+
- 'style="border:0;width:'+this.Config.closeImage.width+'px;height:'+this.Config.closeImage.height+'px;" />';
- return a;
- },
- Resize: function(){
- var w = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.scrollWidth;
- var c = w - this.Config.totalWidth;
- c = c < 0 ? 0 : c;
- var w1 = (w - this.Config.minWidth - c) / 2 - 2;
- var w2 = w1 + 2;
- this.AD[0].style.left = (-w1) + 'px';
- this.AD[0].style.backgroundPosition = - (this.Config.adWidth - w2) + 'px 0';
- this.AD[1].style.right = (-w1) + 'px';
- if(this.IE <= 6)
- this.AD[1].style.backgroundPosition = (this.Config.adWidth - w2) + 'px 0';
- else
- this.AD[1].style.backgroundPosition = (w2 + this.Config.minWidth) + 'px 0';
- this.CD[0].style.left = (-w1) + 'px';
- this.CD[1].style.right = (-w1) + 'px';
- },
- Scroll: function(){
- var t = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
- if(this.IE <= 6 && this.Config.Type > 0){
- this.AD[0].style.backgroundPosition = '0 ' + t + 'px';
- this.AD[1].style.backgroundPosition = 'right ' + t + 'px';
- }
- this.CD[0].style.top = t + 'px';
- this.CD[1].style.top = t + 'px';
- this.Resize();
- },
- Init: function(){
- var nd = new Date();
- var bd = new Date(Date.parse(this.Config.adTime.begin));
- var ed = new Date(Date.parse(this.Config.adTime.end));
- if(!(nd.getTime()>bd.getTime() && nd.getTime()<ed.getTime()))return;
- document.body.style.backgroundColor = this.Config.bgColor;
- document.body.style.background = 'url('+this.Config.bgImage+') fixed';
- if(navigator.appName == "Microsoft Internet Explorer"){
- var userAgent = navigator.userAgent;
- var s = 'MSIE';
- this.IE = parseFloat(userAgent.substr(userAgent.indexOf(s) + s.length));
- }
- this.Config.totalWidth = this.Config.minWidth + this.Config.adWidth * 2;
- this.Div = document.createElement('div');
- with(this.Div.style){
- position = 'relative';
- width = (this.Config.minWidth + 2) + 'px';
- margin = 'auto';
- top = '0';
- zIndex = '0';
- }
- document.body.insertBefore(this.Div, document.body.childNodes[0]);
- this.AD[0] = this.createAd('left');
- this.AD[1] = this.createAd('right');
- this.CD[0] = this.createClose('left');
- this.CD[1] = this.createClose('right');
- this.Div.appendChild(this.AD[0]);
- this.Div.appendChild(this.AD[1]);
- this.Div.appendChild(this.CD[0]);
- this.Div.appendChild(this.CD[1]);
- var self = this;
- if(document.all){
- window.attachEvent("onscroll", function(){self.Scroll();});
- window.attachEvent("onresize", function(){self.Resize();});
- }else{
- window.addEventListener("scroll", function(){self.Scroll();},true);
- window.addEventListener("resize", function(){self.Resize();},true);
- }
- this.Scroll();
- }
- };
调用方法:
- if(document.all){
- window.attachEvent("onload", function(){backgroundAd.Init();});
- }else{
- window.addEventListener("load", function(){backgroundAd.Init();}, true);
- }
纯CSS解决DIV垂直居中的样式
作者:青锋幽灵 日期:2009-07-01 16:43
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>无标题文档</title>
- <style type="text/css">
- .a {width:200px;height:200px;border:1px solid #333;display:table;vertical-align:middle;}
- .a p {position:relative;left:0;top:50%;width:100%;text-align:center;display:table-cell;vertical-align:middle;}
- .a img {height:50px;border:1px solid #f30;position:relative;top:-50%;}
- </style>
- </head>
- <div
- <body>
- <div class="a"><p><img src="http://www.google.com/intl/en/images/logo.gif" /></p></div>
- </body>
- </html>
获取字符串长度的函数(ASP/VB/JS)
作者:青锋幽灵 日期:2009-06-07 21:19
- function strLen(str){
- var len=0;
- for(var i=0;i<str.length;i++){
- var intCode=str.charCodeAt(i);
- if(intCode>=0 && intCode<=128){
- len = len + 1;
- }else{
- len = len + 2;
- }
- }
- return len;
- }
- Function strLen(iTxt)
- Dim txt: txt = Trim(iTxt)
- Dim x: x = Len(txt)
- Dim y: y = 0
- Dim ii
- For ii = 1 To x
- If Asc(Mid(txt, ii, 1)) <= 255 Then
- y = y + 2
- Else
- y = y + 1
- End If
- Next
- strLen = y
- End Function
PHP的MSSql的操作类
作者:青锋幽灵 日期:2009-04-10 10:54
- <?php
- /*MSSql的操作类*/
- class MSSql {
- var $link;
- var $querynum = 0;
- /*连接MSSql数据库,参数:dbsn->数据库服务器地址,dbun->登陆用户名,dbpw->登陆密码,dbname->数据库名字*/
- function Connect($dbsn, $dbun, $dbpw, $dbname) {
- if($this->link = @mssql_connect($dbsn, $dbun, $dbpw, true)) {
- $query = $this->Query('SET TEXTSIZE 2147483647');
- if (@mssql_select_db($dbname, $this->link)) {
- } else {
- $this->halt('Can not Select DataBase');
- }
- } else {
- $this->halt('Can not connect to MSSQL server');
- }
- }
- /*执行sql语句,返回对应的结果标识*/
- function Query($sql) {
- if($query = @mssql_query($sql, $this->link)) {
- $this->querynum++;
- return $query;
- } else {
- $this->querynum++;
- $this->halt('MSSQL Query Error', $sql);
- }
- }
- /*执行Insert Into语句,并返回最后的insert操作所产生的自动增长的id*/
- function Insert($table, $iarr) {
- $value = $this->InsertSql($iarr);
- $query = $this->Query('INSERT INTO ' . $table . ' ' . $value . '; SELECT SCOPE_IDENTITY() AS [insertid];');
- $record = $this->GetRow($query);
- $this->Clear($query);
- return $record['insertid'];
- }
- /*执行Update语句,并返回最后的update操作所影响的行数*/
- function Update($table, $uarr, $condition = '') {
- $value = $this->UpdateSql($uarr);
- if ($condition) {
- $condition = ' WHERE ' . $condition;
- }
- $query = $this->Query('UPDATE ' . $table . ' SET ' . $value . $condition . '; SELECT @@ROWCOUNT AS [rowcount];');
- $record = $this->GetRow($query);
- $this->Clear($query);
- return $record['rowcount'];
- }
- /*执行Delete语句,并返回最后的Delete操作所影响的行数*/
- function Delete($table, $condition = '') {
- if ($condition) {
- $condition = ' WHERE ' . $condition;
- }
- $query = $this->Query('DELETE ' . $table . $condition . '; SELECT @@ROWCOUNT AS [rowcount];');
- $record = $this->GetRow($query);
- $this->Clear($query);
- return $record['rowcount'];
- }
- /*将字符转为可以安全保存的mssql值,比如a'a转为a''a*/
- function EnCode($str) {
- return str_replace(''', '''', str_replace('