设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4308|回复: 9
打印 上一主题 下一主题

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

[复制链接]

Lv3.寻梦者

宛若

梦石
0
星屑
1568
在线时间
526 小时
注册时间
2007-8-19
帖子
1493

极短24参与开拓者

跳转到指定楼层
1
发表于 2010-7-10 21:51:07 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

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

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

x
RT,中文会直接返回false,英文就不会……求解……
另:不是编码问题,已经把文件名字符串编码转换为ANSI一样没用……
[url=http://rpg.blue/thread-219730-1-1.html]http://unhero.sinaapp.com/wi.php[/url]
[color=Red]如你所见这是个死坑,没错这就是打我的脸用的[/color]

Lv2.观梦者

梦石
0
星屑
255
在线时间
24 小时
注册时间
2008-8-2
帖子
128
10
发表于 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
回复 支持 反对

使用道具 举报

Lv1.梦旅人

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

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

使用道具 举报

Lv2.观梦者

梦石
0
星屑
255
在线时间
24 小时
注册时间
2008-8-2
帖子
128
8
发表于 2010-7-11 12:53:41 | 只看该作者
。。。
在游戏目录新建一个文件:

然后再用脚本测试:
  1. p FileTest.exist?("这是中文.txt")  #==>true

  2. exit
复制代码
...

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

点评

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

使用道具 举报

Lv1.梦旅人

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


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

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
6
发表于 2010-7-11 08:56:25 | 只看该作者
真神奇……File.delete或者rename之类的都能支持中文,而FileTest.exist?却不行= =

点评

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

使用道具 举报

Lv3.寻梦者

孤独守望

梦石
0
星屑
3132
在线时间
1535 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

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

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
4
发表于 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 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

彩色的银子

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

贵宾

3
发表于 2010-7-10 21:56:39 | 只看该作者
最简单的。。
open之...异常之....{:nm_7:}

评分

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

查看全部评分

-.-
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6850
在线时间
1666 小时
注册时间
2008-10-29
帖子
6710

贵宾

2
发表于 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 认可答案

查看全部评分












你知道得太多了

回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-6 08:18

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表