• linux下文件名特殊符号导致的一个诡异问题

    写了个bash脚本递归循环遍历文件夹。本地测试的好好的,结果传到服务器上就不行,一直死循环。以为是linux的版本问题,折腾了半天,才发现只有遍历特定那个文件夹的时候才会出现问题。

    最后发现竟然有个文件夹的名字叫

    当遍历到文件夹的时候,路径就成为 /home/image/

    而符号在bash里是转义符号,必须用/home/image/\才行, /home/image/表示的还是 /home/image/。所以导致死循环了。

    然后又实验了一下,linux下的文件夹没有限制字符,所有的可打印字符都可以作文件夹名。比方
    *,,|,等在windows下是不允许做文件夹名的,但linux下就可以。但这样的文件名确实会给用户造成迷惑。比方一个叫
    *的文件夹,用户如果删除的时候忘记转义,输出成  rm -rf *,那就惨了。

     

    不知道linux的设计者为什么没考虑到这个问题?或者说考虑到了,但觉得这样的问题应该让用户自己掌控?

  • css强制换行问题

    1.(IE浏览器)连续的英文字符和阿拉伯数字,使用word-wrap : break-word ;或者word-break:break-all;实现强制断行

    #wrap{word-break:break-all; width:200px;}
    或者
    #wrap{word-wrap:break-word; width:200px;}

    abcdefghijklmnabcdefghijklmnabcdefghijklmn111111111

    效果:可以实现换行

    2.(Firefox浏览器)连续的英文字符和阿拉伯数字的断行,Firefox的所有版本的没有解决这个问题,我们只有让超出边界的字符隐藏或者,给容器添加滚动条

    #wrap{word-break:break-all; width:200px; overflow:auto;}

    abcdefghijklmnabcdefghijklmnabcdefghijklmn111111111

     

     

    firefox下的一个解决方法:

    XBL binding

     

    .wordwrap { -moz-binding: url('./wordwrap.xml#wordwrap'); }
    

     

      wordwrap.xml的内容:

     

    			//
    

     

     

     演示地址:http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take2/

    如果要通用的,跨浏览器的解决方案就只能用javascript

     

    //aka makeDesignerHappy(dEl);
          function breakWord(dEl){
    
            if(!dEl || dEl.nodeType !== 1){
    
              return false;
    
            } else if(dEl.currentStyle && typeof dEl.currentStyle.wordBreak === 'string'){
    
              //Lazy Function Definition Pattern, Peter's Blog
              //From http://peter.michaux.ca/article/3556
    
              breakWord = function(dEl){
                //For Internet Explorer
                dEl.runtimeStyle.wordBreak = 'break-all';
                return true;
              }
    
              return breakWord(dEl);
    
            }else if(document.createTreeWalker){
    
              //Faster Trim in Javascript, Flagrant Badassery
              //http://blog.stevenlevithan.com/archives/faster-trim-javascript
    
              var trim = function  (str) {
                str = str.replace(/^ss*/, '');
                var ws = /s/,
                i = str.length;
                while (ws.test(str.charAt(--i)));
                return str.slice(0, i   1);
              }
    
              //Lazy Function Definition Pattern, Peter's Blog
              //From http://peter.michaux.ca/article/3556
    
              breakWord = function(dEl){
    
                //For Opera, Safari, and Firefox
                var dWalker = document.createTreeWalker(dEl, NodeFilter.SHOW_TEXT, null, false);
                var node,s,c = String.fromCharCode('8203');
                while (dWalker.nextNode())
                {
                  node = dWalker.currentNode;
                  //we need to trim String otherwise Firefox will display
                  //incorect text-indent with space characters
                  s = trim( node.nodeValue ) .split('').join(c);
                  node.nodeValue = s;
                }
                return true;
              }
    
              return breakWord(dEl);
    
            }else{
              return false;
            }
          }
    

     

     

    以上代码来自下面这个网址:

  • Javascript对象中使用setTimeout和setInterval的问题

        前两天写一个js时遇到个问题。就是在js对象内部如果用setTimeout或者setInterval调用该对象的一个方法,然后在被调用方法中就无法使用this获取该对象。因为经过setTimeout调用后,this就成了浏览器了,原来那个对象就丢失了。

          如:

    function TestObj(){
        this.property = "test";
        this.called = function(){
           alert(this.property);
         }
        this.setTimeCall = function(){
             setTimeout(this.called,500);
         }
     }
    
    var test = new TestObj();
    test.setTimeCall();  
    

     

    如果直接调用test.called方法是没有问题的。但如果通过setTimeout调用,也就是调用
    test.setTimeCall(),this.property就为空了。因为这里的this成浏览器了。同样的问题也发生在监听浏览器的其他事件
    上。没办法,于是用了个比较糟糕的办法。

     

    function TestObj(){
       this.property = "test";
       this.called = function(){
           alert(this.property);
    }
       this.setTimeCall = function(){
        setTimeout("test.called()",500);
    }
    }
    var test = new TestObj();
    test.setTimeCall();  
    

     

     之所以说这样做糟糕,是因为在定义TestObj时,就必须提前知道TestObj被创建时的变量名。后来在IBM社区看到一篇探讨javascript有限状态机的文章,用了一个很巧妙的办法避免这个问题。

    function TestObj(){
        this.property = "test";
        var self = this;
         this.called = function(){
             alert(self.property);
         }
    
         this.setTimeCall = function(){
             setTimeout(self.called,500);
         }
     }
    
     var test = new TestObj();
     test.called();
     test.setTimeCall();  
    

     

    在TestObj中定义一个变量,self,然后指向this。这样用self调用this,就不会发生和浏览器的this对象冲突的问题了。

     虽然是很简单的一个问题,但有时候人脑子转不过弯也没办法。

     

    还有一个网友评论提供的办法就是:

     

    function TestObj(){
    
        this.called = function(){
            alert("OK");
        }
    
        this.setTimeCall = function(){
            setTimeout(this.called.bind(this),500);
        }
    }   
    

     

  • mysqldump导出数据到mssql

    mysqldump -u root -ppassword --no-create-db --no-create-info --complete-insert --compatible=mssql
     --default-character-set=utf8 --skip-opt --compact  --extended-insert=false
     dbname tablename|sed "s/\'/''/g">tablename.sql
    

     

    –no-create-db 不输出建database的脚本

    –no-create-info 不输出创建table的脚本

    –complete-insert   完整的插入,输出每个字段(如: insert into table(field1,field2,….) values(value1,value2,…))

    –compatible=mssql 教本兼容格式,这里是mssql 这样教本里就会把table的名字和字段名用“号引起来,而不是mssql不能识别的`号。

    –default-character-set=utf8 默认编码

    –compact 输出尽量少的信息

    –extended-insert=false  禁用它,可以每行生成一句insert语句。否则只输出一个insert,如:insert
    into table
    values(value1,value2,…),(value1,value2,…),…(value1,value2,..)。这种格式
    sqlserver不识别。

     

     

    mysql中用转义 字符串里的 单引号等字符,而sqlserver的字符串中两个单引号表示一个单引号。没找到mysqldump指定转义字符的选项。有个fields-escaped-by选项,但只有在输出文本格式的时候有用,输出sql语句的时候不能用。

     

    所以只好用sed替换一下。

     

    sed "s/\'/''/g"
    

     

  • Spring自动装配(autowire)导致quartz不能运行

    在spring中配置了一个简单的quartz任务,结果报错:

    Failure obtaining db row lock: 第 1 行: 只有 DECLARE CURSOR 才允许使用 FOR UPDATE 子句。
    
    只有 DECLARE CURSOR 才允许使用 FOR UPDATE 子句
    
    at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
    	at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2816)
    	at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2254)
    	at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:631)
    	at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:477)
    	at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:777)
    	at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:91)
    	at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:92)
    

     

    很郁闷,以为是事务控制的问题。

    结果最后发现是自动配置(quartz)的问题。

    spring的SchedulerFactoryBean中有个dataSource属性。如果这个属性不为空,则用数据库来持久化储存quartz的任务。结果正好我的spring中的DataSource的名字就叫dataSource,结果就导致了上面的错误。

    这个哥们也遇到了同样的问题:

    所以spring的autowire还是尽量少用为好。

  • Lucene范围查询(RangeQuery)的几个问题

    对要进行范围查询(RangeQuery)的字段 创建索引的时候要按照 储存 不分词 的方式创建索引。

    new Field(name, value, Field.Store.YES, Field.Index.UN_TOKENIZED);

    1.数字的范围查询

    对数字进行范围查询,必须先把数字格式化为一样长度的字符串。位数不够的在前面补零。

    如:

    NumberFormat format = NumberFormat.getIntegerInstance();
    //设置数字的位数 由实际情况的最大数字决定
    format.setMinimumIntegerDigits(6);
    //是否按每三位隔开,如:1234567 将被格式化为 1,234,567。在这里选择 否
    format.setGroupingUsed(false);
    
    format.format(number);
    

     

    这样 1 将被格式化为 000001

    查询的时候也必须补零。

    查询语法: fieldName:[000001 TO 000100]

    演示:http://so.1ting.com/singer.do?q=singerIdRange:[000001 TO 000100]&sort=singerId

     

    2:日期范围查询

    日期范围查询必须需要用lucene的时间转换工具类(DateTools
    )的

    static String

    dateToString (Date date, DateTools.Resolution resolution)
    方法
    ,先把时间转换为字符串进行索引。

    查询语法: date:[6/1/2005 TO 6/4/2005]

    还可以overwrites
    QueryParser类的getRangeQuery(String, String, String, boolean)方法实现自定义的范围搜索。

     

     

subscribe via RSS