nid's blog

2009-12-17

ftpclient超时时间设置

归类于: 未分类 — nid @ 17:24

使用apacher的commons-net-2.0.jar中的 org.apache.commons.net.ftp.FtpClient有一段时间了。然而程序时不时挂起,无任何反应。很是郁闷,于是详细看了一下它的源码,总算是把超时时间设置给搞定了。

ftpClient.setConnectTimeout(connectTimeOut);//设置 命令连接 超时时间
ftpClient.setDefaultTimeout(dataTimeOut);//设置 命令连接 数据超时时间

ftpClient.setSoTimeout(60*1000);//设置 主动模式下 数据超时时间

一直以为像上面这样设置就没问题了,可事实上并不是这样子,FtpClient并没有直接提供 被动模式下数据连接的连接超时和数据接收超时时间的接口。当然我们可以间接的实现它。需要用到这个方法:

ftpClient.setSocketFactory(factory);

当然我们要创建一个SocketFactory的实例,SocketFactory是一个虚类,我们需要继承一下,于是我写了个MySocketFactory:

public class MySocketFactory extends SocketFactory {
 private int connectTimeOut = 120 * 1000;
 private int dataTimeOut = 60 * 1000; 
 @Override
 public Socket createSocket() throws IOException,
   UnknownHostException {
  Socket socket = new Socket();
  socket.setSoTimeout(dataTimeOut);
  return socket;
 }
 @Override
 public Socket createSocket(String host, int port) throws IOException,
   UnknownHostException {
  InetAddress address = InetAddress.getByName(host);
  return createSocket(address, port, null, 0);  
 }

 @Override
 public Socket createSocket(InetAddress host, int port) throws IOException {
  return createSocket(host, port, null, 0);  
 }

 @Override
 public Socket createSocket(String host, int port, InetAddress localHost,
   int localPort) throws IOException, UnknownHostException {
  InetAddress address = InetAddress.getByName(host);
  return createSocket(address, port, localHost, localPort);
 }

 @Override
 public Socket createSocket(InetAddress address, int port,
   InetAddress localAddress, int localPort) throws IOException {
  Socket socket = new Socket();

  SocketAddress remote = new InetSocketAddress(address, port);
  if (localAddress != null) {
   SocketAddress local = new InetSocketAddress(localAddress, localPort);
   socket.bind(local);
  }
  socket.connect(remote, connectTimeOut);
  socket.setSoTimeout(dataTimeOut);
  return socket;
 }

}

所以为了让FtpClient的超时时间完全生效,我们需要这样写:

ftpClient = new FTPClient();
ftpClient.setConnectTimeout(connectTimeOut);
ftpClient.setDefaultTimeout(dataTimeOut);

ftpClient.setSoTimeout(60*1000);

MySocketFactory factory = new MySocketFactory();
ftpClient.setSocketFactory(factory);

还是相当的麻烦呀。希望下次apache可以修正这个问题

2009-12-02

c#开控制台的代码

归类于: 未分类 — nid @ 11:47

 [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        static private extern bool AllocConsole();

2009-10-29

mysql条件插入(insert)

归类于: 数据库 — nid @ 11:08

我们常常会有这样的需求,当指定记录不存在的时候插入一条新记录。在sql server里面,我们可以用

if not exists (select * from c where id=1) insert into c (id,word) values(1,'nid')

遗憾的是在mysql 里面上面的语句是不支持的。在mysql里面的实现要更复杂一些。看下面的sql语句

INSERT INTO c (id,word) SELECT 1, 'test' from dual WHERE not exists (select * from c where c.id = 1)

dual是一个特殊表

使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中

2009-08-14

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

归类于: 未分类 — nid @ 09:59

来源地址: http://www.blogjava.net/Unmi/archive/2007/11/26/163055.html

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

硬连接指向的是节点(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命令详细用法

2009-07-03

tokyo tyrant java对象反序列化解决方案

归类于: 未分类 — nid @ 15:12

通过修改 com.danga.MemCached.MemCachedClient.java
改两个地方就可以了
MemCachedClient.java 的
public Object get( String key, Integer hashCode, boolean asString ) 方法
约1300行左右

if ( log.isDebugEnabled() ) {
	log.debug( "++++ key: " + key );
	log.debug( "++++ flags: " + flag );
	log.debug( "++++ length: " + length );
}
//插入代码开始
//先读flag
byte[] flagBytes = new byte[4];
sock.read(flagBytes);
flag = NativeHandler.decodeInteger(flagBytes);
length -= 4;
//插入代码结束
// read obj into buffer
byte[] buf = new byte[length];
 
sock.read( buf );
sock.clearEOL();

另一个地方是:

try {
	//change send bytes, flags bytes added by Nid
	String cmd = String.format( "%s %s %d %d %d\r\n", cmdname, key, flags, (expiry.getTime() / 1000),
val.length+4 );//这个地方长度要加4,因为在正文内容前加上了flags
	sock.write( cmd.getBytes() );
       //这里就是在正文发送前,先发送flags
	sock.write(NativeHandler.encode(flags));
	sock.write( val );
	sock.write( "\r\n".getBytes() );
	sock.flush();
PS:如果你需要用到getMulti方法,那么还需要修改loadMulti方法,1625行左右
if ( log.isDebugEnabled() ) {
     log.debug( "++++ key: " + key );
     log.debug( "++++ flags: " + flag );
     log.debug( "++++ length: " + length );
    }
    //modify by nid start
    byte[] flagBytes = new byte[4];
    input.read(flagBytes);
    flag = NativeHandler.decodeInteger(flagBytes);
    length -= 4;
    //modify by nid end
    

参考网页:
http://www.javaeye.com/problems/16445

2009-06-09

Python,mysql,文件 编码问题

归类于: 未分类 — nid @ 14:46

应用情境是这样的,用Python从mysql 中读一些数据出来,并写成一个文本文件

# -*- coding: gbk -*-
import codecs
#指定文件的编码gbk
f1=codecs.open("1.txt","w","gbk")
 
print 'start'
import MySQLdb
import MySQLdb.cursors
#指定数据库的编码utf8
db = MySQLdb.connect(host = '192.168.21.182', user = 'root', passwd = '', \
db = 'mis',charset="utf8",cursorclass = MySQLdb.cursors.DictCursor)
cursor = db.cursor()
 
cursor.execute('select ServerPath from File')
rs = cursor.fetchall()
 
for dict in rs:
	path=dict["ServerPath"]
	f1.write(line)
 
f1.close()
cursor.close()
print 'ok'

参考网页
http://hi.baidu.com/yobin/blog/item/894158b575090dcb37d3ca07.html

2009-06-08

Python实现的简单爬虫

归类于: 未分类 — nid @ 16:43
import urllib
sock = urllib.urlopen("<a href="http://www.pp.tv/">http://www.pp.tv/</a>")
htmlSource = sock.read() 
sock.close() 
print htmlSource.decode("utf-8").encode("gbk")

因为目标网页是UTF-8编码的,然后我的控制台是GBK编码的,所以要转换一下

Python捕获所有异常的办法

归类于: 未分类 — nid @ 11:10
try:
        a = b
        b = c
except Exception,data:
        print Exception,":",data

参考网页:http://developer.51cto.com/art/200902/111535.htm

Python日期时间格式化处理

归类于: 未分类 — nid @ 11:06

代码:

import datetime
time=datetime.datetime.strptime('08/Jun/2009:10:26:44','%d/%b/%Y:%H:%M:%S')
print datetime.datetime.strftime(time,'%Y%m%d%H%M%S')

相关参数说明:
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%j 年内的一天(001-366)
%m 月份(01-12)
%M 分钟数(00=59)
%p 本地A.M.或P.M.的等价符
%S 秒(00-59)
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%Z 当前时区的名称
%% %号本身

参考文章:
http://www.ntsky.com/tech/python/program/2008-12-25/42378d29c074f853.html
http://blog.csdn.net/kernelspirit/archive/2007/11/19/1891984.aspx

2009-05-30

python学习笔记(1)

归类于: 未分类 — nid @ 12:44
最近挺想认真学一下python,同时把一些实用的代码和思路跟大家分享一下,也方便自己以后查看。
今天先开个头吧,不一定能写完,写多少算多少。
先列个大纲吧

字符串
类型转换
正则表达式
数组,列表
字典哈希表

文件操作
调用系统命令,可执行程序
网络爬虫
数据库

如果网友觉得上面的大纲不完善,欢迎补充

下一页 »

Powered by WordPress