5

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?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Senthil Kumar
  • 9,695
  • 8
  • 36
  • 45
  • 1
    Please be aware that a case-insensitive OS are the exception rather than the rule. Windows is pretty much the only major OS left that handles files in a case-insensitive way. – Joachim Sauer Nov 14 '09 at 10:12
  • seems to me a good strategy on windows is to be case-preserving even if not case sensitive. don't have your code reference a file by multiple capitalizations, and don't permute the case of paths you are given. – asveikau Nov 14 '09 at 10:20

7 Answers7

4

Fix it!

Any scheme you devise to circumvent fixing it will be worse in the long run.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
3

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.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
2

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).

Roland Ewald
  • 4,630
  • 3
  • 35
  • 49
1

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

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.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
0

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())
Alexander Torstling
  • 18,552
  • 7
  • 62
  • 74
0

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.

Carl Smotricz
  • 66,391
  • 18
  • 125
  • 167
  • tempted to do this. :P But not advisable right? will follow best programming practices. :) – Senthil Kumar Nov 14 '09 at 10:45
  • We're talking on the order of 100ms overhead for opening a file. If it doesn't happen all that often, this solution would do it. If performance is an issue but the directory doesn't change often, you could cache the directory list. But solving the problem at its root would be the best thing. Are you aware of the "rename" tool on Linux? – Carl Smotricz Nov 14 '09 at 11:09
  • 1
    This only works if it is the filename itself which is incorrectly spelled, not if there problem is in any of the parent directories. – JesperE Aug 15 '14 at 14:33
  • Good point! Of course my kludge could be extended to do the same kind of thing with directory names. – Carl Smotricz Aug 17 '14 at 10:36