查看: 4941|回复: 9

[已经解决] Ruby中的File模块的exists?方法不支持中文?

[复制链接]

宛若

梦石
0
星屑
1888
在线时间
529 小时
注册时间
2007-8-19
回帖
1466

极短24参与开拓者

发表于 2010-7-10 21:51:07 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
RT,中文会直接返回false,英文就不会……求解……
另:不是编码问题,已经把文件名字符串编码转换为ANSI一样没用……
[url=http://rpg.blue/thread-219730-1-1.html]http://unhero.sinaapp.com/wi.php[/url]
[color=Red]如你所见这是个死坑,没错这就是打我的脸用的[/color]
梦石
0
星屑
7095
在线时间
1666 小时
注册时间
2008-10-29
回帖
6612

贵宾

发表于 2010-7-10 21:55:22 | 显示全部楼层
本帖最后由 后知后觉 于 2010-7-10 21:58 编辑

默认的不支持中文
  1. PathFileExists = Win32API.new("shlwapi", "PathFileExistsW", "P", "I")
  2. MultiByteToWideChar = Win32API.new("kernel32", "MultiByteToWideChar", "ILPIPI", "I")
  3. def FileTest.exists?(filename)
  4.   len = MultiByteToWideChar.call(65001, 0, filename, -1, 0, 0) << 1
  5.   buf = " " * len
  6.   MultiByteToWideChar.call(65001, 0, filename, -1, buf, len)
  7.   return PathFileExists.call(buf) == 0 ? false : true
  8. end
复制代码

评分

参与人数 1星屑 +300 收起 理由
「旅」 + 300 认可答案

查看全部评分












你知道得太多了

回复

使用道具 举报

彩色的银子

梦石
0
星屑
50
在线时间
190 小时
注册时间
2006-6-13
回帖
1260

贵宾

发表于 2010-7-10 21:56:39 | 显示全部楼层
最简单的。。
open之...异常之....{:nm_7:}

评分

参与人数 1星屑 +300 收起 理由
「旅」 + 300 认可答案

查看全部评分

-.-
回复

使用道具 举报

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
回帖
1912
发表于 2010-7-11 07:58:14 | 显示全部楼层
本帖最后由 紫苏 于 2010-7-11 07:59 编辑

确实比较诡异,刚看了下源码,没有发现任何改变了文件名字符串的地方,那么 File.exists? 按理说是应该使用当前用户 locale 的代码页的,所以可以用 ANSI 的字符串,但把 ANSI 编码的文件名传给 PathFileExistsA 和 FindFirstFileA 就可以,而 File.exists? 却失败。本来怀疑是由于底层调用了 POSIX 标准的 I/O 函数 stat 而导致的(编码?)问题,但我直接用 Win32 环境下的 CRT 里的 stat 来测试了下,又没有问题,而且 File.open 同样用了 POSIX 标准的 fdopen,也并没有这个问题,难道是由于不同的实现?……|| 等待高手释疑,这里把 File.exists? 方法的例行程序路由贴出来供有兴趣的人研究

FileTest.exists? 的 C 原型是 test_e;

  1. define_filetest_function("exist?", test_e, 1);
  2. define_filetest_function("exists?", test_e, 1); /* temporary */
复制代码
test_e 调用 rb_stat 函数并传递 filename,如果 rb_stat 的返回值小于 1 则返回 false(文件不存在);
test_e: http://ruby-doc.org/doxygen/1.8.4/file_8c-source.html#l01101

rb_stat 调用 StringValueCStr(filename),实则是一个调用了 rb_string_value_cstr(filename) 的宏,将 Ruby 字符串转换为 C 字符串 cstr;
rb_stat:http://ruby-doc.org/doxygen/1.8.4/file_8c-source.html#l00647
StringValueCStr:http://ruby-doc.org/doxygen/1.8.4/ruby_8h-source.html#l00245
rb_string_value_str:http://ruby-doc.org/doxygen/1.8.4/string_8c-source.html#l00565

rb_stat 调用 stat 获取文件状态,stat 返回;rb_stat 返回 stat 返回的值;test_e 返回 rb_stat 返回的值

评分

参与人数 1星屑 +800 收起 理由
「旅」 + 800 认可答案

查看全部评分

回复

使用道具 举报

孤独守望

梦石
0
星屑
3144
在线时间
1535 小时
注册时间
2006-10-16
回帖
4223

开拓者贵宾

发表于 2010-7-11 08:34:49 | 显示全部楼层
我囧了……
  1. a = Dir["*.*"]
  2. p a                           =>最后一个是"你好.txt"
  3. p File.exists?(a.last)   =>false
复制代码
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复

使用道具 举报

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
回帖
2406
发表于 2010-7-11 08:56:25 | 显示全部楼层
真神奇……File.delete或者rename之类的都能支持中文,而FileTest.exist?却不行= =

点评

刚看了下  发表于 2010-7-11 12:06
From mortal hope immortal power springs.
回复

使用道具 举报

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
回帖
1912
发表于 2010-7-11 12:07:23 | 显示全部楼层
真神奇……File.delete或者rename之类的都能支持中文,而FileTest.exist?却不行= =
小幽的马甲 发表于 2010-7-11 08:56


刚又看了下,delete 用的是 unlink,rename 用的就是 rename,都是 POSIX 标准的函数,不知道为什么用到 stat 的时候就有问题……可能在路由过程中有什么我没看到,强烈建议大家去瞅瞅源代码,帮楼主解决问题的同时还能提高代码阅读能力 XD
回复

使用道具 举报

梦石
0
星屑
310
在线时间
24 小时
注册时间
2008-8-2
回帖
117
发表于 2010-7-11 12:53:41 | 显示全部楼层
。。。
在游戏目录新建一个文件:
up.PNG
然后再用脚本测试:
  1. p FileTest.exist?("这是中文.txt")  #==>true

  2. exit
复制代码
...

To 5楼,
用你那脚本,在我的环境里,是TRUE、、、

点评

请注意此乃XP讨论区XP提问…… 经测试VX可通过XP依旧为假……大家去翻Ruby版本的更新目录吧……  发表于 2010-7-11 12:57
GRESK
回复

使用道具 举报

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
回帖
1912
发表于 2010-7-11 13:01:13 | 显示全部楼层
IamI  发表于 35 秒前
请注意此乃XP讨论区XP提问…… 经测试VX可通过XP依旧为假……大家去翻Ruby版本的更新目录吧……

呃,这话倒是提醒我了,VX 没错的话就不是 Ruby 的问题,而是 RMXP 的问题了(莫妮卡你在哪……) 0.- 因为根据 VX 的 about 对话框信息来看,VX 的 Ruby 版本仍然是 1.8.1
回复

使用道具 举报

梦石
0
星屑
310
在线时间
24 小时
注册时间
2008-8-2
回帖
117
发表于 2010-7-11 13:09:00 | 显示全部楼层
ok,我想好了、、

  1. d_s = "" # 这里改搜索目录,别忘了加 /

  2. dir_array = Dir["#{d_s}*.*"]

  3. if dir_array.include?("这是中文.txt")
  4.   p "存在该文件、、、"
  5. end

  6. exit
复制代码

点评

这贴讨论的其实不是如何解决问题,要解决有很多方法(比如 2、3 楼都是正解),主要是讨论为什么有这个现象~  发表于 2010-7-11 13:21
GRESK
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部