Saber 酱的抱枕

Fly me to the moon

07/15
2016
学习

关于PHP操作文件时最长文件名的研究

先吃我大鼻孔

今天我在改进pixiv下载器,想把tag信息保存到文件名里。前两天我研究了“windows中文件名最大长度的问题”,也是为这个做准备。我很快把获取tag的代码写好了,也在php里限制了文件名最大长度。但是做完之后感觉有点不对劲。怎么不对劲呢?下载图片的失败几率比以前大大提高了。错误都是:

Warning:fopen() Invalid argument

那么到底文件名哪里不对呢?这问题折腾了我五六个小时,我下班都没回去,坐在办公室里还在研究这个问题。天见可怜,我终于还是找到了问题的真相。

问题还是出在长度上。

windows计算文件名(包括路径)都是按【字数】算的,也就是说,不管你是中英混合还是怎么的,都能写满256个字。

我以为用php去创建文件也可以这样,于是我在php里用mb_strlen()函数去计算字数,这个函数也是把一个文字当做一个长度算。结果我这样做是错的,php虽然也会限制文件名和路径长度之和不能超过256个字符,但它真的只是字符长度,不是字数。所以php里操作文件时,涉及到文件名长度,要使用strlen()函数。

strlen()的计算方法是,英文占一个字符,而中文字符在gbk编码中算两个字符,在utf8编码中算三个字符。还好我使用的gbk编码,否则能用的字数要更少了。

下面这个路径在php的gbk编码中算做256长度(字节?):

F:\wamp\www\t/pixivimg/专辑1422_ 【一无所有的“死亡回归”!】Re 从零开始的异世界生活特辑 /56938050_p0_tag-ナツキスバル,Re ゼロから始める異世界生活,スバル,菜月昴,ゼロから始める異世界生活,リゼロ,リゼロ500users入り,Re ゼロから始める異世界00usersxxxxxxx入り.jpg

当然,用windows的计算方式,刚到170个长度。

好吧……为了在有限的长度里多给tag腾腾地方,我把文件名里很多东西都去掉了。标题啊,日期啊什么的都扔了,只留下图片id和tag。现在的文件名是这样的:

19566474_p0-よんでますよ、アザゼルさん。,十点じゃ足りません!,ふつくしい,なにこれ綺麗,サラマンダーwwwwww,一体だけ浮いてるw,まんまですよ、マンダはん,アザゼルさん1000users入り,キャプショ.jpg

这个长度已经接近极限了。心好累,感觉不会再爱了。

关于PHP操作文件时最长文件名的研究

  1. locationiskey
    Internet Explorer 11.0Internet Explorer 11.0Windows 7Windows 7

    据说这是由一个全局变量PHP_MAXPATHLEN 设定的,那么这东西能不能改呢
    虽然我觉得会爆炸

    回复
    1. saber 文章作者
      Google Chrome 51Google Chrome 51Windows 7 x64 EditionWindows 7 x64 Edition

      其实有没有这个变量,对于分发的应用来说作用不大。因为很多用户是对这块什么都不懂的小白,更不用指望让他们去修改变量了。

      回复
      1. locationiskey
        Internet Explorer 11.0Internet Explorer 11.0Windows 7Windows 7

        也就是说这个不能在你这里改咯……那就没办法

        (注:其实ntfs也有文件名(不含路径)不大于255的限制似乎……)

        回复
        1. saber 文章作者
          Google Chrome 51Google Chrome 51Windows 7 x64 EditionWindows 7 x64 Edition

          虽然系统支持的文件名长度很长,但是资源管理器和普通程序都只能处理256以内的 没办法

          回复
          1. locationiskey
            Internet Explorer 11.0Internet Explorer 11.0Windows 7Windows 7

            php这么设定好像是为了兼容不同文件系统

            win自己倒是说可以生成长文件名(就是超出上次那个限制的)

            回复
        2. saber 文章作者
          Google Chrome 51Google Chrome 51Windows 7 x64 EditionWindows 7 x64 Edition

          但是资源管理器限制256 没办法,普通人还是得用资源管理器

          回复