# Bug in File.isDirectory()?



## jollyroger (16. Okt 2007)

Hi,

ich hatte ja schon immer den Eindruck das mit File.isDirectory was nicht ganz koscher ist.

Ich bin grade am Bugfixing für das UltraVNC-Applet, dabei ist mir aufgefallen, das beim Filetransfer Fenster oftmals (aber nicht immer) Dateien als Verzeichnisse angezeigt werden, obwohl es 100% Dateien und nicht Verzeichnisse.

Die betreffende Stelle im Code des VNC-Applets sieht so aus:


```
public void changeLocalDirectory(File dir)
	{
			if(DEBUG) System.out.println("inside changeRemoteDrive() / FTPFrame...");
			if(DEBUG) System.out.println("Given parameter File: " + dir.getName());
			currentLocalDirectory = dir;	// Updates Global
			File allFiles[] = dir.listFiles();	// Reads files
			String[] contents = dir.list();

			localList.clear();
			localList.addElement(" [..]");
			
			// sort content list
			Arrays.sort(contents);
			
			// Populate the Lists
			for (int i = 0; i < contents.length; i++)
			{
				if (allFiles[i].isDirectory()) {
					// localList.addElement("[" + contents[i] + "]");
					localDirList.add(" [" + contents[i] + "]"); // sf@2004
					System.out.println(contents[i] + " is a directory");
				}
				else
				{
					// localList.addElement(contents[i]);
					localFileList.add(" " + contents[i]); // sf@2004
					System.out.println(contents[i] + " is a file");
				}
			}
```

Die Methode geht noch weiter, aber ich seh schon hier an der Ausgabe, das was nicht stimmt:


```
jdk-6u2-linux-i586.rpm is a directory
```

Das ist schon mal glatt gelogen:


```
file jdk-6u2-linux-i586.rpm
jdk-6u2-linux-i586.rpm: RPM v3 bin i386 jdk-1.6.0_02-fcs
```

Um nun mögliche Seiteneffekte auszuschließen, hab ich mir obigen Code 1:1 in eine Main-Methode reinkopiert und das nochmal überprüft. Der Code sieht so aus:


```
public class TestShit {
	
	static boolean DEBUG = true;
	static File dir = new File("/home/jollyroger/");  
	static File currentLocalDirectory = null;  
	static Vector localList = new Vector();
	static ArrayList localFileList = new ArrayList();
	static ArrayList localDirList = new ArrayList();
	
	public static void main(String[] args) {

			if(DEBUG) System.out.println("inside changeRemoteDrive() / FTPFrame...");
			if(DEBUG) System.out.println("Given parameter File: " + dir.getName());
			currentLocalDirectory = dir;	// Updates Global
			File allFiles[] = dir.listFiles();	// Reads files
			String[] contents = dir.list();

			localList.clear();
			localList.addElement(" [..]");
			
			// sort content list
			Arrays.sort(contents);
			
			// Populate the Lists
			for (int i = 0; i < contents.length; i++)
			{
				if (allFiles[i].isDirectory()) {
					// localList.addElement("[" + contents[i] + "]");
					localDirList.add(" [" + contents[i] + "]"); // sf@2004
					System.out.println(contents[i] + " is a directory");
				}
				else
				{
					// localList.addElement(contents[i]);
					localFileList.add(" " + contents[i]); // sf@2004
					System.out.println(contents[i] + " is a file");
				}
			}
	}

}
```

Wie ihr seht ist der bis auf die Variablendeklarationen und Initialisierung vor der main-Methode identisch zum Original.

Das Resultat ist auch das gleiche, nämlich wieder: 


```
jdk-6u2-linux-i586.rpm is a directory
```

Wie kann das sein?

Ich hab schon nach einem derartigen Bug gesucht, aber nichts dergleichen gefunden?

Weiss jemand was hier los ist?

System-Infos:

Java:


```
java -version
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)
```

OS:


```
cat /etc/SuSE-release
openSUSE 10.2 (i586)
VERSION = 10.2
```


----------



## SlaterB (16. Okt 2007)

das ist ja mal ein ignorantes Vorgehen,
dein riesiger Code kann doch durchaus mal was falsch machen,
wieso nicht den einfachen Weg gehen?

File f = new File("dein baseDir/jdk-6u2-linux-i586.rpm");
System.out.println("is directory: "+f.isDirectory()); // vielleicht noch auf exist prüfen, um Tippfehler auszuschließen

siehst, läuft, war doch ganz einfach 


so und jetzt verrate ich mal noch nicht sofort, was in deinem Programm schief läuft,
obwohl jeder Hinweis es im Grunde auch schon verrät:
benutze in der Ausgabe (zusätzlich) allFiles_.getName()_


----------



## jollyroger (16. Okt 2007)

Oh Mann, 

ich brauch mehr Kaffee.......wie konnte ich das __nicht__ sehen.........

Nun ja, danke für den Stupser......... :wink:


----------



## SlaterB (16. Okt 2007)

hmm, stimmte jetzt meine Theorie, dass dir.listFiles() und dir.list(); eine andere Reihenfolge haben?
ich glaubte das nach dem Posting immer weniger,
zumal du den Test ja wohl wiederholt hast und bei mir auf Windows die Reihenfolge gleich ist 

edit: ah, du hast ja noch ein sort drin, böse 
obwohl unter Windows die Reihenfolge auch schon alphabetisch ist..


----------



## Murray (16. Okt 2007)

Die Reihenfolge kommt wohl erst durch das explizites Sortieren des contents-Arrays durcheinander.


----------



## jollyroger (16. Okt 2007)

Ja, 

aufgrund dicker Tomaten auf den Augen hab ich dieses fatale


```
Arrays.sort(contents);
```

völlig übersehen......... :wink: 

Was ich trotzdem mehr als nur verwirrend finde:



> listFiles()
> Returns an array of abstract pathnames denoting the *files* in the directory denoted by this abstract pathname.





> list()
> Returns an array of strings naming the *files and directories* in the directory denoted by this abstract pathname.



listFiles() liefert aber auch die directories zurück?


----------



## Murray (16. Okt 2007)

Ja, hier könnte die Dokumentation etwas genauer sein. Wenn man weiter liest, steht es da aber noch:


			
				javadoc hat gesagt.:
			
		

> *listFiles*
> 
> public File[] listFiles()
> 
> ...


----------



## HoaX (16. Okt 2007)

naja, verzeichnisse sind ja nur spezielle dateien ...


----------



## Murray (16. Okt 2007)

HoaX hat gesagt.:
			
		

> naja, verzeichnisse sind ja nur spezielle dateien ...


Natürlich, aber trotzdem kann es schon verwirren, wenn in der Doku bei der einen Methode zwischen beiden unterschieden wird und bei der anderen nicht - zumal es in der Klasse File ja auch die Methoden isFile und isDirectory gibt, die ja doch wieder implizieren, dass "file" hier nicht immer als der gemeinsame Oberbegriff gemeint ist.

Aber die Klasse File kann ja wohl ohnehin nicht als Musterbeispiel für orthogonales Library-Design durchgehen...


----------

