そのため、あきらめてから2年半後、同じ問題が発生しました。コードを廃止されたOracle Forms 10gバージョンに埋め込む必要があるため、1.4.2で問題が発生しました。
誰かが偶然この問題に遭遇し、それを適切に解決することを決定した場合、それはおそらく、CIFSがリモートファイルシステムをマウントするときに行う(非常に)異常なiノードマッピングに関係しており、よりあいまいなバグを引き起こしますそのうちのserverfaultで見つけることができます。このようなマッピングの副作用の1つは、すべてのディレクトリのハードリンク数がゼロになることです。もう1つは、すべてのディレクトリの「サイズ」が、通常の「セクターサイズ以上」ではなく、正確に0であるということです。これは、。でもチェックできますls
。
(プロプライエタリ)ソースコードを調べないとわかりませんが、1.5より前のJavaは、実際にCでreaddir()を呼び出す代わりに、リンクカウントを内部でチェックするなどのショートカットを使用していたと推測できます。これは、マウントされたFSでも同様に機能します。 。
とにかく、2番目の副作用は、ディレクトリがCIFSを使用してマウントされていると疑われる場合を除いて、システムコールに依存しないFileの単純なラッパーを作成するために使用できます。フィルタを使用しているものも含め、他のバージョンのlist
およびlistFiles
関数は内部的java.io.File
に依存してlist()
いるため、それだけをオーバーライドしても問題ありません。
私はlistFiles
戻ってFile[]
こないFileEx[]
ことを気にしなかったので、それを上書きすることを気にしませんでしたが、それは十分に単純なはずです。ls
明らかに、そのコードは、コマンドが便利なUnixライクなシステムでのみ機能します。
package FSTest;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class FileEx extends File
{
public FileEx(String path)
{
super(path);
}
public FileEx(File f)
{
super(f.getAbsolutePath());
}
public String[] list()
{
if (this.canRead() && this.isDirectory())
{
/*
* Checking the length of dir is not the most reliable way to distinguish CIFS mounts.
* However, zero directory length generally indicates something unusual,
* so calling ls on it wouldn't hurt. Ordinary directories don't suffer any overhead this way.
* If this "zero-size" behavior is ever changed by CIFS but list() still won't work,
* it will be safer to call super.list() first and call this.listUsingExec if returned array has 0 elements.
* Though it might have serious performance implications, of course.
*/
if (this.length() > 0)
return super.list();
else
return this.listUsingExec();
}
else
return null;
}
private String[] listUsingExec()
{
Process p;
String command = "/bin/ls -1a " + this.getAbsolutePath();
ArrayList list = new ArrayList();
try
{
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
if (!line.equalsIgnoreCase(".") && !line.equalsIgnoreCase(".."))
list.add(line);
}
String[] ret = new String[list.size()];
list.toArray(ret);
return ret;
}
catch (IOException e)
{
return null;
}
}
}