精华内容
下载资源
问答
  • python打印不合法的文件名 问题 你的程序获取了一个目录中的文件名列表,但是当它试着去打印文件名的时候程序崩溃, 出现了 UnicodeEncodeError 异常和一条奇怪的消息—— surrogates not allowed 。 解决方案 当...

    python打印不合法的文件名

    问题
    你的程序获取了一个目录中的文件名列表,但是当它试着去打印文件名的时候程序崩溃, 出现了 UnicodeEncodeError 异常和一条奇怪的消息—— surrogates not allowed 。

    解决方案
    当打印未知的文件名时,使用下面的方法可以避免这样的错误:
    在这里插入图片描述
    讨论
    这一小节讨论的是在编写必须处理文件系统的程序时一个不太常见但又很棘手的问题。 默认情况下,Python假定所有文件名都已经根据 sys.getfilesystemencoding() 的值编码过了。 但是,有一些文件系统并没有强制要求这样做,因此允许创建文件名没有正确编码的文件。 这种情况不太常见,但是总会有些用户冒险这样做或者是无意之中这样做了( 可能是在一个有缺陷的代码中给 open() 函数传递了一个不合规范的文件名)。

    当执行类似 os.listdir() 这样的函数时,这些不合规范的文件名就会让Python陷入困境。 一方面,它不能仅仅只是丢弃这些不合格的名字。而另一方面,它又不能将这些文件名转换为正确的文本字符串。 Python对这个问题的解决方案是从文件名中获取未解码的字节值比如 \xhh 并将它映射成Unicode字符 \udchh 表示的所谓的”代理编码”。 下面一个例子演示了当一个不合格目录列表中含有一个文件名为bäd.txt(使用Latin-1而不是UTF-8编码)时的样子:
    在这里插入图片描述
    如果你有代码需要操作文件名或者将文件名传递给 open() 这样的函数,一切都能正常工作。 只有当你想要输出文件名时才会碰到些麻烦(比如打印输出到屏幕或日志文件等)。 特别的,当你想打印上面的文件名列表时,你的程序就会崩溃:
    在这里插入图片描述
    程序崩溃的原因就是字符 \udce4 是一个非法的Unicode字符。 它其实是一个被称为代理字符对的双字符组合的后半部分。 由于缺少了前半部分,因此它是个非法的Unicode。 所以,唯一能成功输出的方法就是当遇到不合法文件名时采取相应的补救措施。 比如可以将上述代码修改如下:
    在这里插入图片描述
    在 bad_filename() 函数中怎样处置取决于你自己。 另外一个选择就是通过某种方式重新编码,示例如下:
    在这里插入图片描述
    译者注:

    surrogateescape:
    这种是Python在绝大部分面向OS的API中所使用的错误处理器,
    它能以一种优雅的方式处理由操作系统提供的数据的编码问题。
    在解码出错时会将出错字节存储到一个很少被使用到的Unicode编码范围内。
    在编码时将那些隐藏值又还原回原先解码失败的字节序列。
    它不仅对于OS API非常有用,也能很容易的处理其他情况下的编码错误。
    使用这个版本产生的输出如下:
    在这里插入图片描述
    这一小节主题可能会被大部分读者所忽略。但是如果你在编写依赖文件名和文件系统的关键任务程序时, 就必须得考虑到这个。否则你可能会在某个周末被叫到办公室去调试一些令人费解的错误。

    展开全文
  • 在FAT32的directory entry里,所预留的文件名的长度是8.3格式的,也就是说,文件名是8个字符,后缀名是3个字符,长于这个的就被认为不合法。不太确定这个规定是从FAT12开始的,还是从FAT16开始的,总之在FAT32里依旧...

    长文件名的处理

    在FAT32的directory entry里,所预留的文件名的长度是8.3格式的,也就是说,文件名是8个字符,后缀名是3个字符,长于这个的就被认为不合法。不太确定这个规定是从FAT12开始的,还是从FAT16开始的,总之在FAT32里依旧有这个限制的影子,但FAT32同样也有机制去处理更长的文件名。

    下面是按照第一篇文章一样的方式创建出来的FAT32文件格式的image文件,然后在里面创建一个名字巨长无比的文件,就叫abcdefghijklmnopqrstuvwxyz.txt1234吧,这个是远远突破了8.3格式的要求了,下面是它在FAT32 image里的样子,如图:


    至于为什么会找到0x9e000这个地址,请看FAT32学习笔记(一)里的介绍。

    从这个截图里可以看到,在0x9e060的地方和文件名非常相似,所不同的是创建的文件名是小写,而image里所存储的却是大写,而且,在不考虑长文件名支持的情况下,这个文件读出来会是”ABCDEF~1.TXT”,相信很多人都会有一种特别熟悉的感觉,尤其是这个“xxxx~1.xxx”中的“~1”。接下来就是FAT32中对长文件名的格式定义:

    在data area里,每32 Bytes是一个directory entry。其中,

    offset 0x0 - 0xA是DIR_name,前8个bytes是文件名,后3个bytes是后缀;

    offset 0xB是DIR_attr,该bytes上每个bit的定义如下:

    ATTR_READ_ONLY,0x01

    ATTR_HIDDEN,0x02

    ATTR_SYSTEM,0x04

    ATTR_VOLUME_ID,0x08

    ATTR_DIRECTORY,0x10

    ATTR_ARCHIVE,0x20

    ATTR_LONG_NAME, ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID

    offset 0xC,reserved

    offset 0xD,DIR_CrtTimerTenth,表示文件创建时间的,这里不太关心,所以不详细解释

    offset 0xE - 0xF, DIR_CrtTime,

    offset 0x10 - 0x11, DIR_CrtDate,

    offset 0x12 - 0x13, DIR_LstAccDate,

    offset 0x14 - 0x15, DIR_FstCusHI,表示该文件内容所在的簇的高2个bytes,它将和DIR_FstClusLO一起凑成一个4bytes的数,在这个簇里就能找到该文件的内容。

    offset 0x16 - 0x17, DIR_WrtTime,

    offset 0x18 - 0x19,DIR_WrtDate,

    offset 0x1A - 0x1B,DIR_FstClusLO,和前面的DIR_FstCusHI一起作为文件内容的寻址数。

    offset 0x1C - 0x1F,DIR_FileSize,文件大小。

    注意offset 0xB,DIR_Attr,如果这里是0xF,就表示该entry是LONG_NAME的一部分,此时它的bytes含义就会发生变化


    LONG_NAME部分的directory entry Bytes定义如下:

    offset 0x0,LDIR_Ord,表明该entry在一串LONG_NAME entry中的顺序。如果bit6为1,则该串LONG_NAME entry以这个entry结束。

    offset 0x1 - 0xA, LDIR_Name1,全部是character,

    offset 0xB,LDIR_Attr,必须是ATTR_LONG_NAME,

    offset 0xC, LDIR_Type,如果为0,表明该entry是LONG_NAME entry的一部分,

    offset 0xD, LDIR_Chksum,校验和

    offset 0xE - 0x19, LDIR_Name2,全部是character,

    offset 0x1A - 0x1B,LDIR_FstClusLO,在LONG_NAME entry里没有意义,它存在的意义只是用来和老的tool兼容,

    offset 0x1C - 0x1F,LDIR_Name3,全部是character。


    在了解了长文件名directory entry的定义之后,就很容易从刚才的截图中看出来“abcdefghijklmnopqrstuvwxyz.txt1234”是如何存储在FAT32 image里的了。下图是一个简单的总结:



    文件内容的查找

    在上图中,用黄色表示出来的会组成一个4 bytes的数,图中会组合成0x00000003,表示该entry所表示的文件,它的内容在簇3里,也就是第一幅图中,0x9e200的部分。至于簇3的地址如何计算,还请参考FAT32学习笔记(一)里的内容。

    目录的处理

    使用如下命令在FAT32 image里创建一个目录,就能很清楚的知道“目录”这个东东到底是怎么一回事了
    sudo mount test.img /mnt/
    cd /mnt/
    sudo mkdir test
    cd /test
    touch 1.txt
    touch 2.txt
    echo abcdefg >> 1.txt
    echo 1234567 >> 2.txt
    cd /tmp
    sudo umount /mnt/
    hexdump -C test.img
    得到如下结果:

    从0x9e080开始,是这次新创建的test目录,还是按照刚才的长文件名的处理方式,能够知道该目录的内容在簇4里,也就是0x9e400的地方。在0x9e400的地方,同样的按照长文件名的处理方式,能够找出来如下的directory entry:
    0x9e400,一个directory entry,表示的目录是“.”,从该directory entry里可以看到,它的内容在簇4里,也就是本身,因此,目录“.”表示当前目录。
    0x9e420,一个directory entry,表示的目录是“..”,从该directory entry里可以找到它的内容在簇0里,然而,在FAT32规范里,Data Area是从簇2开始的,到底如何处理有待研究。
    0x9e440,两个directory entry,表示文件1.txt,它的内容在簇5里,也就是0x9e600。
    0x9e480,两个directory entry,表示文件2.txt,它的内容在簇6里,也就是0x9e800。
    按照对应的地址去找,都能看到相应的内容。
    这里还有另外一个问题:目录“.”和目录“..”是FAT32规范的内容,还是Linux自己所定义的?在windows的系统里,应该是没有这样的内容的。等下次在windows系统里用U盘做实验,拿到ubuntu上来观察就可以解答这个疑惑了。到时候再更新这篇文章。
    (还有另外一个方式,把这个test.img放到host machine,挂载到windows的虚拟机上,这样就不需要U盘了。而且,我的U盘用了好久,里面全都被写满了,看起来好凌乱啊,没有这种image看起来清晰)。





    展开全文
  • 大家都知道,一般而言,在windows系统中,为新创建的文件命名时,在保证后缀合法的基础上,还要保证文件名本身也合法,比如能含有某些符号和空格等。但在某些情况下,即使已经将文件命名为合法的名称,仍然存在...

        大家都知道,一般而言,在windows系统中,为新创建的文件命名时,在保证后缀合法的基础上,还要保证文件名本身也合法,比如不能含有某些符号和空格等。但在某些情况下,即使已经将文件命名为合法的名称,仍然存在出现问题的可能,比如下面就会谈到我今天所遇到的情况。

        事情的背景故事是这样的。我,一个C++初学者,在“CodeBlocks”软件下,参考《C++ Primer Plus》进行一些练习。当我为了测试“i++”与“++i”在“for循环”头部的表达式中所产生的效果的区别时(其实是没有区别的),创建了一个名为 “for_update_test.cbp”(起这个名字,是因为“i++”可以被认为是“for循环”头部的“update-expression”部分) 的C++ console 项目,并在该项目下面进行编程和测试。我打开了source下面的main()部分并进行了简单的编程,代码如下:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a[5] ={1,2,3,4,5};
    
        cout << "the situation of i++" << endl;
        for (int i=0;i<5;i++)
        {
            cout << a[i] << endl;
        }
    
        cout << "the situation of ++i" << endl;
        for (int i=0;i<5;++i)
        {
            cout << a[i] << endl;
        }
    
        cin.get();
        return 0;
    }

        这当然是一些最基本的内容,大家谁都会。但在我编译然后运行程序时,出现了意想不到的结果。

        为什么会这样呢?我问我自己。

        首先,我猜测,有可能是我写错了程序吧?于是我就仔细检查了我写的内容,但确实没发现写错什么东西,而且编译时候也没有报错。

       之后,我猜测,是不是我的编译器没有设置对,但我检查了settings->compiler里面的设置,使用的是默认的GNU GCC compiler,除了新勾选的C++11这个功能,也没有任何奇怪的内容。

        然后,我猜测,也许是我的CodeBlocks软件有bug?于是我上百度和谷歌搜索我这个情况,也没有找到相同的情况。一般不能运行程序都是因为编译器有问题,但我的编译器明明是没有问题的。这就令人费解了。而且更令我惊讶的是,我试了一些以前编写的其他项目里程序,都可以完全正常的运行。

        在不知所措的情况下,我重启了我的电脑,然而重启之后这个程序依然运行不下去,依然是得到上面的结果。而我之前编写的其他项目程序依然可以运行。但在我新建的这个项目里面,我甚至连一个“hello world”都运行不了,仍然得到上面的“Process returned 4258096”,而这个错误代码根本也搜索不到。

        在重启电脑也不能解决问题的情况下,我怀疑我的CodeBlocks软件本身有问题,于是立刻卸载重装。然而重装之后,该程序依然不能运行。

        我居然连一个“hello world”都无法运行了?虽然是一个初学者,但我觉得我不能连这样一个问题都解决不掉。

        我认为,我的突破口在于我之前编写的其他项目代码仍然可用,我只有从这个“不能运行的代码”和我之前编写的“可用的代码”之间找出区别,才能找到解决问题的方法。事实上,确实也是如此。

        仔细排查了从“创建新项目”到“代码编译运行”的所有流程,我发现,这次编写的内容,除了项目名称之外,没有任何设置上的区别,因此我认为问题很大程度上是出在新创建的项目的名称上的。于是我又新创建了好几个“C++ console”项目,例如“forupdatetest.cbp”以及“for_test.cbp”和“fccc.cbp”等,然后把相同代码粘贴到它们的main()函数中进行编译运行,结果发现,“forupdatetest.cbp”项目也出现了不能运行的情况,而“for_test.cbp”和“fccc.cbp”则可以运行。

        这激起了我强烈的兴趣。难道一个项目文件名就可以影响代码的运行?!

        为了了解更多细节,我关闭了CodeBlocks软件界面,打开储存文件的路径检查文件,结果确实发现了一些线索。

        “for_update_test.cbp”所生成的.exe可执行文件居然是带有“护盾”标识的文件!

        反观“for_test.cbp”所生成的.exe可执行文件,就没有这样的标识。

        试着点开这个带“护盾”的可执行文件,会出现特殊的效果,即“是否允许更改”等字样,可以选择“是”来执行这个程序。

        之后,就出现了正常该执行该代码的结果,如下:

        之后还会弹出如下所示的一个窗口:

        我隐隐约约感觉到这个可执行文件的不寻常,感觉它有点像一些Windows系统自带的文件。我猜测,也许是“update”这个词命中了Windows系统的一些检测机制。也许,整个问题,就出在这个文件当中包含这个“update”词汇上。

        为此,我建立了一些新的包含“update”字眼的C++ console 项目文件来测试它们生成的可执行文件是否会出现特殊效果。结果确实如我所想。

       

        凡是“显式”或者“隐式”包含“update”字样的C++ console项目,都会生成带有“护盾”标志的可执行文件,且它们在CodeBlocks环境中都是可以正常编译,但无法正常运行的。因此我推测,CodeBlocks环境运行已经编译的代码时,其实也是在间接调用由该项目生成的可执行文件,而一旦这个可执行文件带有“护盾”,即需要更多权限才能打开时,CodeBlocks环境就无法正常运行这个程序。

        与之形成对比的是不带有“update”字样或者错误拼写“update”字样的项目文件,都不会生成带有“护盾”的可执行文件。

        这说明了什么?

        我的推断是:Windows系统会自动识别显式或者隐式带有“update”字眼的可执行文件,并在用户运行该文件前进行询问,目的可能是保护系统或者其他我所不了解的功能。而我这次恰好由于建立了带有“update”字眼的项目并生成了带有“update”字眼的可执行文件,导致了CodeBlocks环境无法正常运行编译好的程序。

        这次意外导致我花费了几个小时去排查问题,过程很崩溃、很郁闷,但结果还算比较圆满。虽然没能彻底弄清楚里面的机制,但至少明白了一点,就是“给项目命名时绝对不要出现‘update’字眼”,因为这样会让计算机自动生成带有“护盾”的可执行程序(经调查,这个“护盾”功能是系统生成的防止其他软件未经授权自动运行的),会导致后期的运行时出现一些小问题。

        通过这次经历,我深深体会到,我们学习编程,除了了解代码的写法,更应该增加对计算机本身的了解。毕竟计算机是一个我们出生之前几十年就被发明出来的一种设备,其中绝大部分结构和功能对我们来说都是“黑箱系统”,是只可以见其运行结果而不可见其运行过程的。

        我觉得,如果希望能够更好地利用这个博大精深的工具,那么最好的办法就是了解它的内部设计,让这个“黑箱系统”变成“灰箱系统”,甚至“白箱系统”。只有在“知己知彼”的情况下,才能让我们设计的程序发挥出它最好的效果,实现“计算机为人服务”的最终目的。

    展开全文
  • 1018 0x000003FA 尝试在标示为删除的系统登录机码,执行不合法的操作。 1019 0x000003FB 系统无法配置系统登录记录所需的空间。 1020 0x000003FC 无法在已经有子机码或数值的系统登录机码建立符号连结。 1021 0x...
  • 程序出现逻辑错误或者用户输入不合法都会引起异常,但这些异常并不是致命,不会导致程序崩溃死掉。可以利用Python提供异常处理机制,在异常出现时候及时捕获,并从内部消化掉。 看下面的这个例子,当用户输入...

    目录

     

    一、什么是异常

    二、异常的总结


    一、什么是异常

    程序出现逻辑错误或者用户输入不合法都会引起异常,但这些异常并不是致命的,不会导致程序崩溃死掉。可以利用Python提供的异常处理机制,在异常出现的时候及时捕获,并从内部消化掉。

    看下面的这个例子,当用户输入一个不存在的文件名,那么程序就会报错:

    file_name = input('请输入需要打开的文件名:')
    f = open(file_name)
    print('文件的内容是:')
    for each_line in f:
        print(each_line)

    抛出一个FileNotFoundError的异常

    Traceback (most recent call last):
      File "C:/Users/ZPWX/AppData/Local/Programs/Python/Python37/源码/032/note1.py", line 2, in <module>
        f = open(file_name)
    FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'

    二、异常的总结

    • AssertionError:断言语句(assert)失败

    断言语句在关于分支和循环的章节里讲过。当assert这个关键字后边的条件为假的时候,程序将停止并抛出AssertionError异常。assert语句一般是在测试程序的时候用于在代码中置入检查点:

    >>> my_list = ['我爱Pyhon']
    >>> assert len(my_list) > 0
    >>> my_list.pop ()
    '我爱Pyhon'
    >>> assert len(my_list) > 0
    Traceback (most recent call last):
      File "<pyshell#4>", line 1, in <module>
        assert len(my_list) > 0
    AssertionError
    • AttributeError:尝试访问未知的对象属性
    >>> my_list.fishc
    Traceback (most recent call last):
      File "<pyshell#6>", line 1, in <module>
        my_list.fishc
    AttributeError: 'list' object has no attribute 'fishc'
    • IndexError:索引超出序列的范围
    >>> my_list = [1,2,3]
    >>> my_list[3]
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        my_list[3]
    IndexError: list index out of range
    >>> my_list[2]
    3
    • KeyError:字典中查找一个不存在的关键字
    >>> my_dict = {'one':1,'two':2,'three':3}
    >>> my_dict['one']
    1
    >>> my_dict['four']
    Traceback (most recent call last):
      File "<pyshell#13>", line 1, in <module>
        my_dict['four']
    KeyError: 'four'

    字典不支持索引,可以用get()方法来查找,当查找不存在的关键字,不会报错

    • NameError:尝试访问一个不存在的变量

    当尝试访问一个不存在的变量时,Python会抛出此类异常

    >>> fishc
    Traceback (most recent call last):
      File "<pyshell#15>", line 1, in <module>
        fishc
    NameError: name 'fishc' is not defined
    • OSError:操作系统产生的异常

    OSError顾名思义就是操作系统产生的异常,像打开一个不存在的文件会引发FileNotFoundError,而这个FileNotFoundError就是OSError的子类。例子上面已经演示过,这里就不重复了。

    • SyntaxError:python语法错误

    遇到此类错误是Python语法的错误,这是Python的代码并不能继续执行,应该先找到并改正错误:

    >>> print 'i love python'
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print('i love python')?
    • TypeError:不同类型间的无效操作
    >>> 1 + '1'
    Traceback (most recent call last):
      File "<pyshell#20>", line 1, in <module>
        1 + '1'
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    • ZeroDivisionError:除数为零
    >>> 5 / 0
    Traceback (most recent call last):
      File "<pyshell#19>", line 1, in <module>
        5 / 0
    ZeroDivisionError: division by zero

    Python标准异常总结点击这里

    展开全文
  • 下面的情况是弹出框中要求用户输入文件名, 并在点击确定时检查文件名的合法性, 不合法则提示用户重新输入, 弹出框要保持在界面上。 点击取消时弹出框消失。 这里通过对控件反射来实现:  /**our button ...
  • 点击dialog按钮关闭dialog

    千次阅读 2012-10-15 16:30:14
    /** ...  * 但是有情况下我们不需要立即关闭窗口。... * 并在点击确定时检查文件名的合法性, 不合法则提示用户重新输入, 弹出框要保持在界面上  * 使用反射  */  DialogInterface.OnClickL
  • 下面的情况是弹出框中要求用户输入文件名, * 并在点击确定时检查文件名的合法性, 不合法则提示用户重新输入, 弹出框要保持在界面上 * 使用反射 */ DialogInterface.OnClickListener dial...
  • Java中变量与常量

    2021-02-01 12:53:59
    标识符可以简单地理解为一个名字,用来标识类名、变量名、方法名、数组名、文件名的有效字符序列。 Java语言规定标识符由任意顺序字母、下划线(_)、美元符号($)和数字组成,并且第一个字符能是数字。标识符...
  • 在程序中对文件操作是非常常见,而对文件操作则可避免需要文件路径,并对文件路径进行一系列操作,例如:判断已知路径是一个目录还是一个文件,路劲是一个...判断给出路径或者文件名是否合法 Path.G
  • 你可以受限制获得源码,甚至可以从中加进你自己需要特色。PHP在大多数Unix平台,GUN/Linux和微软Windows平台上均可以运行。怎样在Windows环境PC机器或Unix机器上安装PHP资料可以在PHP官方站点上找到。安装...
  •  先判断给定的是不是一个合法的目录,如果不是,则提示给定错误  如果是目录,那么使用File.listFile()获得这个目录下文件名的数组  循环遍历输出这个数组元素  输出名称之后,接着判断这个元素是文件还是...
  • 一个合法的标识符只能由:字母、数字、下划线、美元符 组成,能含有其他符号; 能以数字开头; 严格区分大小写; 关键字能做标识符; 理论上没有长度限制,但最好不要太长。 下面的标识...
  • 你必须知道495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.19 为什么能像下面这样在初始式和数组维度值中使用const值?constintn=5;inta[n]; 1.20 constchar*p、charconst*p和char*constp有什么区别? 复杂声明 1.21 怎样建立和理解非常复杂声明?例如定义一个...
  • 这样是合法的和可移植的吗? 23  2.8 我听说结构可以赋给变量也可以对函数传入和传出。为什么K&R1却明确说明能这样做? 25 2.9 为什么能用内建的==和!=操作符比较结构? 26 2.10 结构传递和返回是如何实现...
  • 《你必须知道495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    这样是合法的和可移植的吗? 23  2.8 我听说结构可以赋给变量也可以对函数传入和传出。为什么K&R1却明确说明能这样做? 25 2.9 为什么能用内建的==和!=操作符比较结构? 26 2.10 结构传递和返回是如何实现...
  • 糖果软件

    2014-08-03 20:08:35
    检查文件名的合法性): Del [URL=http://3800cc.com/news/w31/file://?c:]?c:[/URL] 文件路 径 lpt1 原因五:无效文件名称 如果文件名中包括一个无效名称, 例如文件名有一个尾随空格, 或一个尾 随...
  • Java语法基础(2)

    2019-05-13 16:26:00
    标识符可以简单理解为一个名字,用来标识类名、变量名、方法名、数组名、文件名的有效字符序列。如图所示。 Java语言规定标识符由任意顺序字母、下划线(_)、美元符号($)和数字组成,并且第一个字符能是...
  • XYZ.C ┌──┴┬─┬───┐ QR.C NA.C A.TXT B.C 如果当前盘为C盘,A盘的当前目录为\D2,则下列对A盘上文件QR.C的指定中,合法的是 A)\D2\D4\QR.C B)D4\QR.C C)A:D4\QR.C D)A:D2\D4\QR.C C 2
  • 27、重命名:并是自定义文件名,这个名字是根据每个文件的第一行,并且提取每个文件的第一行作为新的文件名,旧的文件名也可以自定义保留。 说明:如果第一行没有合法的数据可以作为文件名,则顺延至第二行,...
  • 意思是说:filename不合法。 我检查了一下没发现有什么错。然后又一个标签一个标签检查,也没发现错。 后来才注意到最后面正则表达式:意思是 文件名必须是"小写字母","0~9"数字,下划线" —" 和"." [2011...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

下面不合法的文件名是