2009-11-08 5 views
19

私は、Javaでファイルを操作するいくつかのクラスを開発しました。私はLinuxボックスで作業していて、new File("path/to/some/file");と入力してください。コミットする時間が来たとき、私はこのプロジェクトの他の開発者の一部がWindowsを使用していることに気付きました。私は今、フォームに"/path/to/some/file"の文字列を取り込むことができ、OSに応じて、正しく区切られたパスを返すメソッドを呼びたいと思います。文字列パスを正しいファイル区切り文字を使用するように変換するJavaユーティリティはありますか?

例:
"path/to/some/file"は、Windowsでは"path\\to\\some\\file"になります。
Linuxでは、指定されたStringを返します。

これを行う正規表現をノックするのに時間がかかりませんが、私はホイールを再発明するつもりはなく、適切にテストされたソリューションを好むでしょう。それがJDKに組み込まれていればいいかもしれませんが、それが小さなF/OSSライブラリの一部であっても問題ありません。

正しいファイル区切り文字を使用するように文字列パスを変換するJavaユーティリティはありますか?

答えて

32

Apache Commonsが(再び)救助に来ます。 Commons IOメソッドFileNameUtilsseparatorsToSystem()はあなたが望むことをします。

言うまでもなく、Apache Commons IOはさらに多くのことを行い、さらに検討する価値があります。

+9

は、なぜ人々は1を書くことを避けるために肥大化した依存関係を追加することを示唆しておくんなディレクトリを検索しないように、再び、Linuxのファイル構造が異なっているかどうか確認していない申し訳ありませんコード行? – cletus

+13

私はApache Commonsを膨大な依存関係と見なしません。それは私がApache Commons LangとIOを最近不可欠であると考える傾向があるほどです。 –

+7

さらに、1行のコードでいくつのバグが見つかりますか?どのくらい多くの前提条件とエッジケースが見逃されていますか? –

16

"/path/to/some/file"実際には、Windows VistaおよびXPではです。

new java.io.File("/path/to/some/file").getAbsoluteFile() 

> C:\path\to\some\file 

しかし、Windowsが複数rootsを持っているとして、それはまだポータブルではないです。ルートディレクトリは何らかの方法で選択する必要があります。相対パスには問題はありません。

編集:

はApache Commonsの IO UNIX &窓以外のENVSとない助けを行います。 Apache io source code

public static String separatorsToSystem(String path) { 
    if (path == null) { 
    return null; 
    } 
    if (isSystemWindows()) { 
     return separatorsToWindows(path); 
    } else { 
     return separatorsToUnix(path); 
    } 
} 
+0

+1:そうです。私はすでにこのことを見ているまで、この答えを投稿しようとしていました。 – BalusC

+0

ああ、私は追加する必要があります:使用されるルートディスクは、現在の作業ディレクトリが(問題のJavaコードを実行した場所)と同じルートディスクです。 – BalusC

+1

Javaをサポートするすべてのプラットフォームで動作しますか? – Grundlefleck

2

は、あなたがパスを表す文字列を構築するために

System.getProperty("file.separator") 

を使用するオプションを持っていますか?

+0

はい、文字列を作成したくありませんでした。これが非常に一般的なものでなければならないと思って、私はそのトリックをしたコードの既存のスニペットを再利用したかったのです。 – Grundlefleck

+1

あなたがパスを持っているどこでもスラッシュを使用していれば、これはうまくいくようです。 'String fileSep = System.getProperty(" file.separator "); \t文字列パス= "パス/ to/some/file"; \t path.replaceAll( "/"、fileSep); ' – Adam

+0

ええ、トーマスユングは彼の答えでそれを言いました。私にはニュースでした:) – Grundlefleck

0

言うには十分ではないはずです。

"path"+File.Seperator+"to"+File.Seperator+"some"+File.Seperator+"file" 
+1

他のコメントで述べたように、はい、私は単純な文字列置換戦略が有効であることを知っていましたが、文字列をハッキングするとコードが読みにくくなり、誤った入力ミス。テストされ、判読可能なソリューションを使用することは、ここでの目標の1つでした。 – Grundlefleck

3

新しいJava 7では、彼らは、これはあなたが正確に何をしたい行うことができますパスと呼ばれるクラスが含まれていた(http://docs.oracle.com/javase/tutorial/essential/io/pathOps.htmlを参照)

こちら

String rootStorePath = Paths.get("c:/projects/mystuff/").toString(); 
+4

申し訳ありません:これはクロスプラットフォームでは動作しません。パスは現在のOSを想定しています。あなたの例はWindowsのパスのように見えますが、すでにLinuxのエンコーディングを持っています(おそらくそれがうまくいった理由です)。 LinuxのボックスでWindowsのパスを試すと、そのディレクトリは解釈されません。例:Paths.get( "c:\\ projects \\ mystuff")。getParent()はnullを返します。 –

3

これは、Apache Commonsの-ioは、コードの行のカップルに繰り出され、何をするかです::

例です。 210
String separatorsToSystem(String path) { 
    if (res==null) return null; 
    if (File.separatorChar=='\\') { 
     // From Windows to Linux/Mac 
     return res.replace('/', File.separatorChar); 
    } else { 
     // From Linux/Mac to Windows 
     return res.replace('\\', File.separatorChar); 
    } 
} 

余分な依存関係を避けたい場合は、それを使用してください。この7年後にやろうとしている人のため

2

、ApacheのコモンズseparatorsToSystem方法はFilenameUtilsクラスに移動されている:例えば、少なくともでも混在パスを使用してWindowsと完全に

FilenameUtils.separatorsToSystem(String path) 
0
String fileName = Paths.get(fileName).toString(); 

作品を、

C:\ Users \ユーザー名/ MyProjectと\ myfilesという/ myfolderなど

012となり
c:\users\username\myproject\myfiles\myfolder 

Linuxは上記の作るだろうが、あなたは

関連する問題