• ベストアンサー

java.io.Fileクラスは絶対パス長をチェックしないのですか?

windows XP+Eclipse3.3+JDK1.5.0_15上でjava.io.Fileクラスを使ってテキストファイルの入出力を行うJavaプログラムを作成しました。 しかし、これによって、パス長が長すぎて(フルパスで300文字)アクセスできないファイルが作成されてしまいました。 (正確には、Windowsのファイルエクスプローラーに存在は表示されているけど、開けないし、削除も、ドラッグアンドドロップもできないという状態。このファイルの右クリックメニューの項目は「開く」と「送る」の2つしかありませんでした。) StreamReader・WriterもIOExceptionを返していませんでした。 Fileクラスは読み書きするにあたってパス長のチェックをしていないのでしょうか? ちなみに、フルパス長259文字のテキストファイル(数行の文字列を記入してある)を入力に与えたとき、空ファイルのように扱われていました。 このファイルをメモ帳で開こうとすると「パス長が長すぎる」というエラーが出て中身が読み取れませんでした。 以下にソース(例外処理を省略)を抜粋します。 ---------------- File inputFile = new File(args[i]); if (!inputFile.isFile() || !inputFile.canRead()) { // ファイルを読む inputStream = new FileInputStream(inputFile); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "UTF-8"); bufferReader = new BufferedReader(inputStreamReader);   (以下、読み出し処理) // 入力ファイルと同じ階層に「Result」ディレクトリを作る File resultDir = new File(resultDirPath); resultDir.mkdir(); // 読み取った1行の末尾に"a"を付加したものをファイルに書き込み、 // 「Result」ディレクトリに出力。 // ファイル名は「output_(入力テキストファイル名)」とする File outputFile = new File(resultDir.getOutputDirPath(), outputFileName); outputFile.createNewFile(); outputStream = new FileOutputStream(outputFile); outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8"); bufferedWriter = new BufferedWriter(outputStreamWriter);   (以下、書き込み処理) } ---------------- 以上、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#94983
noname#94983
回答No.5

プログラムを実行し、最大パス長を超えてファイルが作れない!となれば、ネイティブ環境側(OS側)で問題が発生するわけで、それを受けて(Javaのプログラム内では)例外が発生する。例外が起こらずファイル保存できたということは、OS側で問題なくファイルが作成できた、すなわち最大パス長以内でファイルができている、ということ。したがって、Java側のクラスに、現在動いているネイティブ環境に合わせたファイルの最大パス長をチェックする仕組みが必要とは思われない。 XPで採用されているNTFSというファイルシステムでは、最大パス長は255でも259でも260でもなく、32768になる。したがって、ファイルのパス長が300文字なら全く問題は起こらない。300文字のパスのファイルが作成できるのは当然だし、できないほうがおかしい。 ただし、現実問題として、エクスプローラを始めとする大半のWindows用プログラムが、それ以前のWindowsで採用されていたFAT32ファイルシステムとの下位互換性を保つために、すべて「最大32768文字」に対応しておらず、わざと(XPのファイルシステムであるNTFSではなく、それよりも古い)FAT32に準拠した最大パス長の制約内でしか動かないように作られているため、それらのプログラムでファイルが利用できないに過ぎない。 だから、これはきわめてWindows的な問題であると思う。Windowsの下位互換にあわせて最大パス長を調整する、というのであれば、自分で実装するしかないと思う。

SSMSE
質問者

お礼

お礼が遅くなりました。 最終的に、受理する最大パス長を255文字までにする、という制約を設けるという方法をとりました。 結局 > フルパス長259文字のテキストファイル(数行の文字列を記入してある)を入力に与えたとき、空ファイルのように扱われていました。 の原因はわからずじまいでしたが・・・上記の制約によってこの現象が起きることを防げるので、とりあえずはよいことにしようと思います。

SSMSE
質問者

補足

> XPで採用されているNTFSというファイルシステムでは、最大パス長は255でも259でも260でもなく、32768になる。 (中略) > FAT32に準拠した最大パス長の制約内でしか動かないように作られているため、それらのプログラムでファイルが利用できないに過ぎない。 なるほど、そういうことだったのですね! エクスプローラーでは存在を確認できる→OS的には問題なくファイルとして取り扱われている メモ帳で開けない→メモ帳自体に課せられた制約のせい というように、それぞれの事象の原因はちがっていたのですね。 上記を踏まえて、パス長をどう扱うか、再考してみたいと思います。 丁寧な説明をいただき、有難うございました。

その他の回答 (4)

  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.4

>> ファイル名の文字数制限は、OSまたはそのファイルシステムによって異なります。 >これは理解しています。 これを理解しておられながら、ご自身でフィルタを設計しようとされないのはなぜですか? >C言語ではよくパス長をチェックするロジックにお目にかかった(多数の検索結果を得た)のですが、 >Javaではそういうのはないのでしょうか? C言語のものを移植するのでは、問題があるのですか? 第三者には、MacOS7でもFAT32でもアクセスできる必要があるのか等、使用環境を想定できないので、 フィルタを設計する方法はないと思うのですが、何をお望みなのでしょう。 >そもそも、なぜ、普通にはアクセスできないようなファイルを読み出したり、 >新規作成したりできるのでしょうか? javaで書き込んだファイルがjavaで読み出せないというような事象が起こっていますか? 最小限のサンプルコードをお示しください。

SSMSE
質問者

補足

> javaで書き込んだファイルがjavaで読み出せないというような事象が起こっていますか? 上記に関しては未検証です。 ただ、質問の中でも述べていますが、 > フルパス長259文字のテキストファイル(数行の文字列を記入してある)を入力に与えたとき、空ファイルのように扱われていました。 という事象が起こっているため、これはファイルオープンなどの例外がスローされてしかるべきではないのか?と疑問に思ったのです。

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.3

windowsでは、短いファイル名という別名(というかMSDOS時代の古い記述法)でアクセスすることが出来ます ファイル名だけでなくディレクトリー名も8文字+.+3文字拡張子に削ってアクセスします。 短いファイル名で、255バイト以内に収まれば、メモ帳でも短いファイル名でアクセス可能なはずです。これがwindowsのファイルパスの限界だったと記憶してますが。 例 D:\web\web_page\HTML4Transitional\長ーーーーーーーい.html ↓短いファイル名モード 8文字+.+3文字拡張子 D:\web\web_page\HTML4T~1\長ーー~1.HTM java.io.Fileクラスが直接この変換をやってるのか、JVMで変換してるのかOS側で変換しているのかまでは、やってみたことはないので解りませんが。

SSMSE
質問者

補足

こんな方法があったとは・・・ インターネット一時ファイルや%temp%フォルダに格納されているファイルで、提示いただいたような名前のものを見かけたことがありますが、あれはきっとこういうことだったのですね。 ひとつ勉強になりました。

  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.2

ファイル名の文字数制限は、OSまたはそのファイルシステムによって異なります。 ですから、java.io.Fileクラスは絶対パス長をチェックすることはできません。

SSMSE
質問者

補足

> ファイル名の文字数制限は、OSまたはそのファイルシステムによって異なります。 これは理解しています。 C言語ではよくパス長をチェックするロジックにお目にかかった(多数の検索結果を得た)のですが、Javaではそういうのはないのでしょうか? そもそも、なぜ、普通にはアクセスできないようなファイルを読み出したり、新規作成したりできるのでしょうか?

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

java.io.File インタフェイスみたいですけど。 javadocに、ファイルのパス長をチェックしてくれるような記述はないので、 java.io.File によるチェックは行われないみたいですね。

SSMSE
質問者

補足

javadocには、確かにパス長については何一つ言及していませんね・・・ java.io.Fileも、FileInputStreamも、InputStreamReaderも、 BufferedReaderも・・・標準アプリケーション(メモ帳)でさえ読み出せないようなデータをなぜ例外を吐かずに読んでいるのか、非常に不思議です。 Javaでファイルパス長をチェックするようなサンプルソースなどがないか検索してみたのですが、見つけることができませんでした。 誰もそんなチェックを実装していない、ということなんでしょうかね・・・??

関連するQ&A