How to avoid FileNotFound exception when running Java on Linux because of case sensitiveness?
My web application runs on Windows. I would like to run my app on Linux also. I seem to have overcome most of the problems such as path separator, etc.
Real problem now is I get FileNotFoundException
when the Java开发者_运维技巧 code tries to open a file say Abc.txt
when only abc.txt
exists. :(
I can't go on changing all the filenames to lowercase or uppercase as i have a whole lot of files. Without changing code much is that any possible way to avoid this?
Fix it!
Any scheme you devise to circumvent fixing it will be worse in the long run.
There is no way to avoid this as the java.io.File
API is system-dependent. You have to use the right case when manipulating files on Linux/Unix. Actually, my advice/solution would be to follow strict and portable conventions during development on Windows (e.g. use lower case filenames only or, better, use the exact file name when accessing it programmatically). To be honest, I don't understand why you are trying to load Abc.txt
when the filename is abc.txt
. This is a bad habit (taught by spending too much time on Windows) rather than a Linux/Unix problem.
Well, first of all I think you should consider moving to a consistent naming scheme, rather than to use some workaround.
Anyway, what about reading in all file names and putting them into a map that contains the lower-case name as a key? You can then look up the correct file name from the map.
This would also allow you to detect a conflict, e.g. two files "FileA.txt" and "FILEA.TXT" in the same directory that have the same lower-case representations, in which case you know that you have to tackle the problem in a completely different way (because you have to know which one you want to have opened, and it's ambiguous, and such a workaround won't do it then).
Assuming that the files are mixed case on Linux, there is no simple answer to this.
The best I can think of is to have your application list the relevant directories and create an in memory data structure of the actual Linux filenames. Then to do a case-insensitive file open, you split the pathname into components, search the in-memory tree using case-insensitive search, bulid the real (case-sensitive) pathname and use THAT to do the file open.
The problem with this is that it (and indeed your app) cannot cope with the case where you have (say) "foo.txt" AND "Foo.txt" in the same Linux directory.
But the best solution is to change your application so that it works with case-sensitive pathnames.
Why can't you change a lot of files? If the amount of files is really the only thing that holds you back, then simply write a little script that renames them all to lower-case.
It's not clear from your question what is causing the case change of your files. If all your files are lowercase in linux, while they are mixed case on windows, you could just transform the filename to lower case, like so:
new File(filename.toLowerCase())
There's a solution that has horrible runtime performance but is very simple to implement:
Replace new FileReader(name)
with something like
openFile(name);
public FileReader openFile(String name) throws FileNotFoundException {
File dir = (new File(name)).getParentFile();
for (File f : dir.listFiles()) {
if (f.getName().equalsIgnoreCase(name)) {
return new FileReader(f);
}
throw new FileNotFoundException("File not found: " + name);
}
I haven't compiled this code, it may have typos and bugs. I leave them to you to fix.
精彩评论