単純なテキストファイルを文字列に読み込もうとしています。もちろん、入力ストリームを取得してreadLine()で繰り返し、内容をStringに読み込む通常の方法があります。
過去何百回もこれまで行ってきたが、最低限のコード行でこれを実行するにはどうすればよいのだろうか。 JavaにはString fileContents = XXX.readFile(myFile/*File*/)
のようなものはありません。
私はApache Commons IOのような単純化を提供するライブラリがあることを知っています。あるいはこれを行うための単純なUtilクラスを書くことさえできます。しかし、私が疑問に思うのはこれだけです。これは非常に頻繁に行われる操作であり、誰もが必要とするのです。なぜJavaはこんな単純な機能を提供しないのでしょうか。デフォルトのエンコーディングまたは指定されたエンコーディングを使用してファイルを文字列に読み込むための単一の方法が本当にないのでしょうか。
はい、あなたはこれを一行で行うことができます(堅牢なIOException
処理のためにあなたは望まないでしょうが)。
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
これは Java.util.Scanner
を使用して、文字列アンカーの末尾である\Z
で入力を区切るように指示します。これにより、最終的に入力に1つの実際のトークン(ファイル全体)が含まれるようになります。したがって、next()
を1回呼び出すだけで読み取ることができます。
コンストラクタ はFile
とString charSetName
を取ります(他の多くのオーバーロードの中で)。これら2つのコンストラクタはFileNotFoundException
をスローすることがありますが、すべてのScanner
メソッドと同様に、これらのコンストラクタを超えてIOException
をスローすることはできません。
Scanner
が発生したかどうかにかかわらず、 ioException()
メソッドを介してIOException
自体を照会できます。また、内容を読んだ後に close()
Scanner
を明示的に指定することもできます。そのため、おそらくローカル変数にScanner
参照を格納するのが最善です。
完全を期すために、これらの非常に評判が良く、非常に有用なサードパーティーのライブラリーがあるならば、これらは本当に良いオプションです:
com.google.common.io.Files
にはたくさんの便利なメソッドが含まれています。ここに適切なものがあります:
String toString(File, Charset)
String
に読み込みます。List<String> readLines(File, Charset)
List<String>
に読み込みます。org.Apache.commons.io.IOUtils
も同様の機能を提供します。
String toString(InputStream, String encoding)
InputStream
の内容をString
として取得します。List readLines(InputStream, String encoding)
List
の(生の)String
として、1行に1エントリJava 7 (API Description) 以降では、次のことが可能です。
new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
FilePathはロードするファイルを表す文字列です。
あなたはApache commons IOを使うことができます。
FileInputStream fisTargetFile = new FileInputStream(new File("test.txt"));
String targetFileStr = IOUtils.toString(fisTargetFile, "UTF-8");
これはあなたのために働くはずです:
import Java.io.IOException;
import Java.nio.file.Files;
import Java.nio.file.Paths;
public static void main(String[] args) throws IOException {
String content = new String(Files.readAllBytes(Paths.get("abc.Java")));
}
Apache Commons IO を使用します。
import org.Apache.commons.io.FileUtils;
//...
String contents = FileUtils.readFileToString(new File("/path/to/the/file"), "UTF-8")
その方法についてはde javadocをご覧ください。 詳細については/ /をご覧ください。
これをするためにあなた自身のutilクラスを書かないでください - 私は Guava を使うことをお勧めします。この場合は、 Files
クラス(実際にファイルを読んでいるだけの場合)または CharStreams のいずれかを一般的な目的のために使用します。データを文字列のリスト(readLines
)または全体(toString
)に読み込むためのメソッドがあります。
バイナリデータにも同様の便利なメソッドがあります。そして、ライブラリの残りの部分があります...
標準ライブラリに似たものが何もないのは厄介だと思います。一体、CharSet
をFileReader
に渡すことができれば、人生は little simpleになります。
他の代替アプローチは:
ファイルの内容からJava文字列を作成する方法を教えてください。
他の選択肢は、オープンソースライブラリで提供されているユーティリティを使用することです。
http://commons.Apache.org/io/api-1.4/index.html?org/Apache/commons/io/IOUtils.html
なぜJavaがそのような共通のutil APIを提供しないのですか?
a) APIを一般的なものにして、エンコード、バッファリングなどがプログラマによって処理されるようにします。
b) プログラマにいくつかの作業を行わせ、オープンソースのutilライブラリを書き込み/共有させる:D ;-)
悲しいことに、いいえ。
このような頻繁な操作では、ループ内で1行ずつ入力をコピーするよりも簡単に実装できるはずですが、ヘルパーメソッドを作成するか外部ライブラリを使用する必要があります。
\\Z
がファイルに含まれている可能性があるので、受け入れられた答えが実際には必ずしもうまくいかないことを私は発見しました。別の問題は、あなたが正しい文字セットを持っていないなら、スキャナがファイルの一部だけを読むことを引き起こすかもしれない予期しないことの全体の束が起こるかもしれないということです。
解決策は、ファイル内に絶対に現れない区切り文字を使用することです。しかし、これは理論的に不可能です。できることは、ファイル内で発生する可能性がごくわずかであるような、区切り文字を使用することです。そのような区切り文字は、Javaでネイティブにサポートされている _ uuid _ です。
String content = new Scanner(file, "UTF-8")
.useDelimiter(UUID.randomUUID().toString()).next();