概要
Java 1.7以降の標準APIのみで行えるファイルコピーのおさらいです。
環境
- Windows 10 Professional
- OpenJDK 10.0.1
参考
- [Oracle JDK 9ドキュメント] (https://docs.oracle.com/javase/jp/9/index.html)
- [Oracle JDK 10ドキュメント] (https://docs.oracle.com/javase/jp/10/index.html)
Files#copy() (Java 1.7+)
- [Files (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/nio/file/Files.html)
Java 1.7で追加されたFilesクラスのcopyメソッドを使う方法です。
public static long copy(InputStream in, Path target, CopyOption... options) throws IOException
public static long copy(Path source, OutputStream out) throws IOException
public static Path copy(Path source, Path target, CopyOption... options) throws IOException
コード例1
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
Files.copy(source, target);
コピー先のファイルを上書きしたい場合はコピーオプションにREPLACE_EXISTINGを指定します。
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
任意のディレクトリへコピーしたい場合。
この例では"path/to/in.txt"を"path/to/newDir/in.txt"へコピーします。
Path source = Paths.get("path/to/in.txt");
Path targetDir = Paths.get("path/to/newDir");
Files.copy(source, targetDir.resolve(source.getFileName()));
コード例2
InputStream source = Files.newInputStream(Paths.get("path/to/in.txt"));
Path target = Paths.get("path/to/out.txt");
try (source) {
Files.copy(source, target);
}
InputStream.transferTo (Java 9+)
- [InputStream (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/InputStream.html)
InputStreamクラスにJava 9で追加されたtransferToメソッドを使う方法です。
public long transferTo(OutputStream out) throws IOException
transferToは、JavaDoc(機械翻訳)に記載されている通りreader/writerのストリームを閉じません。
この入力ストリームからすべてのバイトを読み込んで、指定された出力ストリームに読み込まれた順序でバイトを書き込みます。 戻り時に、この入力ストリームはストリームの終わりにあります。 このメソッドはいずれのストリームも閉じません。
既知のサブクラス
()の値はそのクラス、インターフェースが導入されたJavaのバージョン。
InputStream (1.0)
|
+--- javax.sound.sampled.AudioInputStream (1.3)
|
+--- ByteArrayInputStream (1.0)
|
+--- FileInputStream (1.0)
|
+--- FilterInputStream (1.0)
| |
| +--- BufferedInputStream (1.0)
| +--- java.util.zip.CheckedInputStream (1.1)
| +--- javax.crypto.CipherInputStream (1.4)
| +--- DataInputStream (1.0)
| +--- java.util.zip.DeflaterInputStream (1.6)
| +--- java.security.DigestInputStream (1.2)
| +--- java.util.zip.InflaterInputStream (1.1)
| | @Deprecated
| +--- LineNumberInputStream (1.0)
| +--- javax.swing.ProgressMonitorInputStream (1.2)
| +--- PushbackInputStream (1.0)
|
+--- org.omg.CORBA.portable.InputStream
|
+--- ObjectInputStream (1.1)
|
+--- PipedInputStream (1.0)
|
+--- SequenceInputStream (1.0)
|
| @Deprecated
+--- StringBufferInputStream (1.0)
FileInputStream.transferTo
- [FileInputStream (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/FileInputStream.html)
コード例1
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
try (InputStream in = new FileInputStream(source.toFile());
OutputStream out = new FileOutputStream(target.toFile())) {
in.transferTo(out);
}
コード例1 (Java 9+)
Java 9からはリソースをtry句の外側で宣言できるようになっています。
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
InputStream in = new FileInputStream(source.toFile());
OutputStream out = new FileOutputStream(target.toFile());
try (in; out) {
in.transferTo(out);
}
コード例2
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
try (InputStream in = Files.newInputStream(source);
OutputStream out = Files.newOutputStream(target)) {
in.transferTo(out);
}
コード例2 (Java 9+)
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
InputStream in = Files.newInputStream(source);
OutputStream out = Files.newOutputStream(target);
try (in; out) {
in.transferTo(out);
}
Reader.transferTo (Java 10+)
- [Reader (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/Reader.html)
ReaderクラスにJava 10で追加されたtransferToメソッドを使う方法です。
public long transferTo(Writer out) throws IOException
transferToは、JavaDoc(機械翻訳)に記載されている通りreader/writerのストリームを閉じません。
このリーダーからすべての文字を読み込み、指定されたライターに読み込まれた順番で書き込みます。 戻ってくると、このリーダーはストリームの最後にあります。 このメソッドは、リーダーまたはライターのいずれも閉じません。
既知のサブクラス
()の値はそのクラス、インターフェースが導入されたJavaのバージョン。
Reader
|
+--- BufferedReader (1.1)
| |
| +--- LineNumberReader (1.1)
|
+--- CharArrayReader (1.1)
|
+--- FilterReader (1.1)
| |
| +--- PushbackReader (1.1)
|
+--- InputStreamReader (1.1)
| |
| +--- FileReader (1.1)
|
+--- PipedReader (1.1)
|
+--- StringReader (1.1)
|
+--- jdk.nashorn.api.scripting.URLReader (1.8u40)
FileReader.transferTo
- [FileReader (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/FileReader.html)
コード例
Path source = Paths.get("path/to/in.txt");
Path target = Paths.get("path/to/out.txt");
Reader in = new FileReader(source.toFile());
Writer out = new FileWriter(target.toFile());
try (in; out) {
in.transferTo(out);
}
BufferedReader.transferTo
- [BufferedReader (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/BufferedReader.html)
InputStreamReaderやFileReaderはBufferedReaderでラップすることが推奨されています。
一般的に、Readerに対して読込み要求が出されると、それに対応するベースとなる文字型ストリームまたはバイト・ストリームへの読込み要求が発行されます。 このため、FileReaderやInputStreamReaderのようにread()オペレーションの効率の良くないReaderでは、その周りをBufferedReaderでラップすることをお薦めします。
同様にOutputStreamWriterやFileWriterはBufferedWriterでラップすることが推奨されています。
一般的に、Writerは、その出力をただちにベースとなる文字型ストリームまたはバイト・ストリームに送信します。 プロンプト出力を必要とする場合以外では、FileWriterやOutputStreamWriterのようなWriterから直接write()オペレーションを呼び出すのは効率が悪いので、BufferedWriterでラップすることをお薦めします。
コード例
FileReaderのコード例を下記のように書き直すことができます。
BufferedReader in = new BufferedReader(new FileReader(source.toFile()));
BufferedWriter out = new BufferedWriter(new FileWriter(target.toFile()));
try (in; out) {
in.transferTo(out);
}
StringReader.transferTo
- [StringReader (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/java/io/StringReader.html)
コード例
String source = "あめんぼ\nあかいな\nあいうえお";
Path target = Paths.get("path/to/out.txt");
Reader in = new StringReader(source);
Writer out = new FileWriter(target.toFile());
try (in; out) {
in.transferTo(out);
}
URLReader.transferTo
- [URLReader (Java SE 10 & JDK 10)] (https://docs.oracle.com/javase/jp/10/docs/api/jdk/nashorn/api/scripting/URLReader.html)
URLReaderクラスはJava 1.8u40で追加されました。
Java 11で廃止予定です([JEP 335: Deprecate the Nashorn JavaScript Engine] (http://openjdk.java.net/jeps/335))。
コード例
URI source = URI.create("http://www.oracle.com/technetwork/java/index.html");
Path target = Paths.get("path/to/out.txt");
Reader in = new URLReader(source.toURL(), StandardCharsets.UTF_8);
Writer out = new FileWriter(target.toFile());
try (in; out) {
in.transferTo(out);
}
(WIP) Files#writeString (Java 11+)
FilesクラスにJava 11で追加されたwriteStringメソッドを使う方法です。
public static Path writeString(Path path, CharSequence csq, OpenOption... options) throws IOException
public static Path writeString(Path path, CharSequence csq, Charset cs, OpenOption... options) throws IOException