From: Luke Bayes Date: 2007-06-13T03:15:03+09:00 Subject: File.exists? ignores file extension on windows? I just wanted to check in with an issue I ran into last night. I was trying to unpack a zip file using the following code which appears to be the recommended way to extract using this library. ------------------------------8<------------------------------ Zip::ZipFile::open(zip_file) do |zf| zf.each do |e| fpath = File.join(dir, e.name) FileUtils.mkdir_p(File.dirname(fpath)) zf.extract(e, fpath) end end ------------------------------>8------------------------------ Unfortunately for me, the archive I was extracting contained two sibling files: 1) bin/fcsh.exe 2) bin/fcsh One is obviously an executable and the other is an extension-free shell script that points at it. The Zip archive was raising a ZipDestinationFileExistsError every time it encountered the second, extension-free file (I am attempting to build cross-platform tools and was testing in Cygwin and DOS on Windows XP). As it turns out, the problem isn't in the Zip library at all, but is in the Windows version of Ruby File.exists?(). ------------------------------8<------------------------------ I was able to faithfully reproduce the problem as follows: FileUtils.touch('fcsh.exe') puts "exists?: #{File.exists?('fcsh')}" # exists?: true ------------------------------>8------------------------------ Another interesting issue was that File.move also raises when you attempt to move on top of what Ruby believes is an existing file, while File.copy doesn't seem to mind the 'existing' file. It was also fascinating that even though File.exists? was returning true, if I tried to do anything with that 'existing' file, I would get FileNotFound exceptions. As it turned out, this is the hack that I came up with at midnight last night, is there a different/better workaround that other folks know about? ------------------------------8<------------------------------ Zip::ZipFile::open(zip_file) do |zf| zf.each do |e| fpath = File.join(dir, e.name) FileUtils.mkdir_p(File.dirname(fpath)) if(File.exists?(fpath) && !File.directory?(fpath)) hackpath = fpath + 'hack' zf.extract(e, hackpath) File.copy(hackpath, fpath) File.delete(hackpath) else zf.extract(e, fpath) end end end ------------------------------>8------------------------------ I did some quick google searches for this problem and didn't find any mentions of it. Where do you folks search for answers to problems like this? I know that with Java, C#, JavaScript and ActionScript, I'm usually able to just fire up google and put in the language and exception name - this usually brings me to someone with a similar problem. I haven't found that to be the case with Ruby. Are there any websites or blogs you have found (or written) that are focused on developing cross platform ruby client code? What resources do you keep at the top of your list for Ruby development? Thanks, Luke Bayes http://www.asserttrue.com