JDK-6526865 : File.{compareTo,equals}() wrong for some file names (win)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-02-20
  • Updated: 2010-04-04
  • Resolved: 2009-02-16
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The Windows file system compares file names by converting characters to upper case (using Unicode rules, not locale sensitive). On Windows the File.equals and File.compareTo methods compare file names by first converting to upper case and then converting to lower case. This is the same as the String.CASE_INSENSITIVE_COMPARATOR. Unfortunaely the extra conversion to lower case produces wrong results for some characters. One example of such a character pair are the two upper case I letters (one without a dot and the Turkish one that has a dot). These are both lower cased to a lower case i with a dot. The attached code demonstrates that Windows considers these to be different files.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached code in a directory to which you have write access (it creates two small files).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
String compare: 0
File compare:  a negative number
File equals: false
Length file a: 8
Length file b:28

ACTUAL -
String compare: 0
File compare: 0
File equals: true
Length file a: 8
Length file b:28


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;

public class BugFileComparision
{
	public static void main(String[] arg) throws FileNotFoundException
	{
		String a = "I";
		String b = "\u0130";	// Turkish dotted capital I
		File fa = new File(a);
		File fb = new File(b);
		System.out.println("String compare: "+a.compareToIgnoreCase(b));
		System.out.println("File compare: "+fa.compareTo(fb));
		System.out.println("File equals: "+fa.equals(fb));
		PrintWriter out = new PrintWriter(fa);
		out.println("File a");
		out.close();
		out = new PrintWriter(fb);
		out.println("File b, is slightly longer");
		out.close();
		System.out.println("Length file a: "+fa.length());
		System.out.println("Length file b:"+fb.length());
	}
}

---------- END SOURCE ----------

Comments
EVALUATION It is too risky to change java.io.File after all these years. The new file system API defined by JSR-203 does the right thing and compares paths on Windows in uppercase (as per recommendation from Microsoft).
16-02-2009