Java Language
ファイルI / O
サーチ…
前書き
Java I / O (Input and Output)は、入力を処理して出力を生成するために使用されます。 JavaはI / O操作を高速化するためにストリームという概念を使用しています。 java.ioパッケージには、入出力操作に必要なすべてのクラスが含まれています。 ファイルの処理は、Java I / O APIによってJavaでも行われます。
すべてのバイトをバイト[]に読み込む
Java 7は非常に便利なファイルクラスを導入
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
Path path = Paths.get("path/to/file");
try {
byte[] data = Files.readAllBytes(path);
} catch(IOException e) {
e.printStackTrace();
}
ファイルから画像を読み込む
import java.awt.Image;
import javax.imageio.ImageIO;
...
try {
Image img = ImageIO.read(new File("~/Desktop/cat.png"));
} catch (IOException e) {
e.printStackTrace();
}
バイト[]をファイルに書き込む
byte[] bytes = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };
try(FileOutputStream stream = new FileOutputStream("Hello world.txt")) {
stream.write(bytes);
} catch (IOException ioe) {
// Handle I/O Exception
ioe.printStackTrace();
}
byte[] bytes = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };
FileOutputStream stream = null;
try {
stream = new FileOutputStream("Hello world.txt");
stream.write(bytes);
} catch (IOException ioe) {
// Handle I/O Exception
ioe.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ignored) {}
}
}
ほとんどのjava.ioファイルAPIは、引数としてString
とFile
の両方を受け入れます。
File file = new File("Hello world.txt");
FileOutputStream stream = new FileOutputStream(file);
Stream vs Writer / Reader API
ストリームはバイナリコンテンツへの最も直接的なアクセスを提供するので、 InputStream
/ OutputStream
実装は常にint
とbyte
動作しbyte
。
// Read a single byte from the stream
int b = inputStream.read();
if (b >= 0) { // A negative value represents the end of the stream, normal values are in the range 0 - 255
// Write the byte to another stream
outputStream.write(b);
}
// Read a chunk
byte[] data = new byte[1024];
int nBytesRead = inputStream.read(data);
if (nBytesRead >= 0) { // A negative value represents end of stream
// Write the chunk to another stream
outputStream.write(data, 0, nBytesRead);
}
いくつかの例外があります。おそらくPrintStream
は、「さまざまなデータ値の表現を便利に印刷する機能」を追加しています。これにより、 System.out.println()
などのメソッドを使用して、バイナリInputStream
とテキスト出力の両方としてSystem.out
を使用できます。
また、一部のストリーム実装は、Javaオブジェクト( DataOutputStream
参照)やネイティブ型( DataOutputStream
/ DataInputStream
など)などの上位レベルのコンテンツへのインタフェースとして機能します。
Writer
クラスとReader
クラスでは、Javaは明示的な文字ストリーム用のAPIも提供しています。ほとんどのアプリケーションはこれらの実装をストリームに基づいていますが、文字ストリームAPIはバイナリコンテンツのメソッドを公開しません。
// This example uses the platform's default charset, see below
// for a better implementation.
Writer writer = new OutputStreamWriter(System.out);
writer.write("Hello world!");
Reader reader = new InputStreamReader(System.in);
char singleCharacter = reader.read();
文字をバイナリデータにエンコードする必要があるときはいつでも(たとえばInputStreamWriter
/ OutputStreamWriter
クラスを使用するとき)、プラットフォームのデフォルトのcharsetに依存したくない場合は、charsetを指定する必要があります。不確かな場合は、すべてのJavaプラットフォームでサポートされているUTF-8などのUnicode互換のエンコーディングを使用してください。したがって、 FileWriter
やFileReader
ようなクラスは、常にデフォルトのプラットフォームのcharsetを使用するクラスから離れている必要があります。文字ストリームを使用してファイルにアクセスするより良い方法は次のとおりです。
Charset myCharset = StandardCharsets.UTF_8;
Writer writer = new OutputStreamWriter( new FileOutputStream("test.txt"), myCharset );
writer.write('Ä');
writer.flush();
writer.close();
Reader reader = new InputStreamReader( new FileInputStream("test.txt"), myCharset );
char someUnicodeCharacter = reader.read();
reader.close();
最も一般的に使用されるReader
の1つはBufferedReader
これは別のリーダーからのテキスト行全体を読み取るメソッドを提供し、行ごとに文字ストリームを読み込む最も簡単な方法です:
// Read from baseReader, one line at a time
BufferedReader reader = new BufferedReader( baseReader );
String line;
while((line = reader.readLine()) != null) {
// Remember: System.out is a stream, not a writer!
System.out.println(line);
}
一度にファイル全体を読む
File f = new File(path);
String content = new Scanner(f).useDelimiter("\\Z").next();
\ ZはEOF(ファイルの終わり)記号です。区切り文字として設定すると、スキャナはEOFフラグに達するまで塗りつぶしを読み込みます。
スキャナーでファイルを読む
行単位でファイルを読み込む
public class Main {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(new File("example.txt"));
while(scanner.hasNextLine())
{
String line = scanner.nextLine();
//do stuff
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
一語一語
public class Main {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(new File("example.txt"));
while(scanner.hasNext())
{
String line = scanner.next();
//do stuff
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
また、scanner.useDelimeter()メソッドを使用して区切り文字を変更することもできます
ディレクトリをフィルタリングし、ファイル拡張子でフィルタリングする
public void iterateAndFilter() throws IOException {
Path dir = Paths.get("C:/foo/bar");
PathMatcher imageFileMatcher =
FileSystems.getDefault().getPathMatcher(
"regex:.*(?i:jpg|jpeg|png|gif|bmp|jpe|jfif)");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir,
entry -> imageFileMatcher.matches(entry.getFileName()))) {
for (Path path : stream) {
System.out.println(path.getFileName());
}
}
}
java.io.FileからJava 7への移行NIO(java.nio.file.Path)
これらの例では、Java 7のNIOが一般的であることを既に知っており、 java.io.File
使用してコードを書くことに慣れていることを前提としています。これらの例を使用して、移行のためのNIO中心のドキュメントをすばやく見つけることができます。
Java 7のNIOには、 メモリマップされたファイルや、FileSystemを使ってZIPファイルやJARファイルを開くなどの機能があります 。これらの例は、限られた数の基本的なユースケースをカバーするだけです。
基本的なルールとして、 java.io.File
インスタンス・メソッドを使用してファイル・システムの読み取り/書き込み操作を実行する場合、 java.nio.file.Files
内の静的メソッドとして検出されます。
パスを指す
// -> IO
File file = new File("io.txt");
// -> NIO
Path path = Paths.get("nio.txt");
別のパスに関連するパス
// Forward slashes can be used in place of backslashes even on a Windows operating system
// -> IO
File folder = new File("C:/");
File fileInFolder = new File(folder, "io.txt");
// -> NIO
Path directory = Paths.get("C:/");
Path pathInDirectory = directory.resolve("nio.txt");
ライブラリとの使用のためのファイルのパスの変換
// -> IO to NIO
Path pathFromFile = new File("io.txt").toPath();
// -> NIO to IO
File fileFromPath = Paths.get("nio.txt").toFile();
ファイルが存在するかどうかをチェックし、存在する場合は削除します
// -> IO
if (file.exists()) {
boolean deleted = file.delete();
if (!deleted) {
throw new IOException("Unable to delete file");
}
}
// -> NIO
Files.deleteIfExists(path);
OutputStream経由でファイルに書き込む
FileChannel
、 Files.write(Path path, byte\[\] bytes, OpenOption... options)
など、さまざまなパフォーマンスとメモリの制約、読みやすさと使用例でNIOを使用してファイルから読み書きする方法はいくつかありFiles.write(Path path, byte\[\] bytes, OpenOption... options)
。 ..この例では、 OutputStream
のみをOutputStream
ますが、メモリマップファイルとjava.nio.file.Files
利用可能なさまざまな静的メソッドについて学ぶことを強くお勧めします。
List<String> lines = Arrays.asList(
String.valueOf(Calendar.getInstance().getTimeInMillis()),
"line one",
"line two");
// -> IO
if (file.exists()) {
// Note: Not atomic
throw new IOException("File already exists");
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
for (String line : lines) {
outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
}
}
// -> NIO
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)) {
for (String line : lines) {
outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
}
}
フォルダ内の各ファイルを繰り返し処理する
// -> IO
for (File selectedFile : folder.listFiles()) {
// Note: Depending on the number of files in the directory folder.listFiles() may take a long time to return
System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
}
// -> NIO
Files.walkFileTree(directory, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path selectedPath, BasicFileAttributes attrs) throws IOException {
System.out.println("d " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
System.out.println("f " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
});
再帰的フォルダの反復
// -> IO
recurseFolder(folder);
// -> NIO
// Note: Symbolic links are NOT followed unless explicitly passed as an argument to Files.walkFileTree
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("d " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
System.out.println("f " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
});
private static void recurseFolder(File folder) {
for (File selectedFile : folder.listFiles()) {
System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
if (selectedFile.isDirectory()) {
// Note: Symbolic links are followed
recurseFolder(selectedFile);
}
}
}
FileInputStream / FileOutputStreamを使用したファイルの読み書き
ファイルに書き込むtest.txt:
String filepath ="C:\\test.txt";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filepath);
byte[] buffer = "This will be written in test.txt".getBytes();
fos.write(buffer, 0, buffer.length);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fos != null)
fos.close();
}
ファイルtest.txtからの読み取り:
String filepath ="C:\\test.txt";
FileInputStream fis = null;
try {
fis = new FileInputStream(filepath);
int length = (int) new File(filepath).length();
byte[] buffer = new byte[length];
fis.read(buffer, 0, length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fis != null)
fis.close();
}
Java 1.7以来、 try-with-resourcesステートメントが導入されたことで、読み書き操作の実装はずっと簡単になりました。
ファイルに書き込むtest.txt:
String filepath ="C:\\test.txt";
try (FileOutputStream fos = new FileOutputStream(filepath)){
byte[] buffer = "This will be written in test.txt".getBytes();
fos.write(buffer, 0, buffer.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ファイルtest.txtからの読み取り:
String filepath ="C:\\test.txt";
try (FileInputStream fis = new FileInputStream(filepath)){
int length = (int) new File(filepath).length();
byte[] buffer = new byte[length];
fis.read(buffer, 0, length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
バイナリファイルからの読み込み
Javaのすべての最新バージョンで、次のコードを使用してバイナリファイルを読むことができます。
File file = new File("path_to_the_file");
byte[] data = new byte[(int) file.length()];
DataInputStream stream = new DataInputStream(new FileInputStream(file));
stream.readFully(data);
stream.close();
Java 7以降を使用している場合は、 nio API
を使用するより簡単な方法がありnio API
。
Path path = Paths.get("path_to_the_file");
byte [] data = Files.readAllBytes(path);
ロッキング
ファイルは、入力出力streams
およびreaders
から取得できるFileChannel
APIを使用してロックできます
streams
例
//ファイルストリームを開きますFileInputStream ios = new FileInputStream(filename); //ファイルストリームを開きます。
// get underlying channel
FileChannel channel = ios.getChannel();
/*
* try to lock the file. true means whether the lock is shared or not i.e. multiple processes can acquire a
* shared lock (for reading only) Using false with readable channel only will generate an exception. You should
* use a writable channel (taken from FileOutputStream) when using false. tryLock will always return immediately
*/
FileLock lock = channel.tryLock(0, Long.MAX_VALUE, true);
if (lock == null) {
System.out.println("Unable to acquire lock");
} else {
System.out.println("Lock acquired successfully");
}
// you can also use blocking call which will block until a lock is acquired.
channel.lock();
// Once you have completed desired operations of file. release the lock
if (lock != null) {
lock.release();
}
// close the file stream afterwards
// Example with reader
RandomAccessFile randomAccessFile = new RandomAccessFile(filename, "rw");
FileChannel channel = randomAccessFile.getChannel();
//repeat the same steps as above but now you can use shared as true or false as the channel is in read write mode
InputStreamとOutputStreamを使用したファイルのコピー
ループを使用して、ソースからデータシンクにデータを直接コピーできます。この例では、InputStreamからデータを読み込むと同時に、OutputStreamに書き込んでいます。読み書きが終わると、リソースを閉じる必要があります。
public void copy(InputStream source, OutputStream destination) throws IOException {
try {
int c;
while ((c = source.read()) != -1) {
destination.write(c);
}
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
チャネルとバッファを使用したファイルの読み込み
Channel
は、データを読み書きするためにBuffer
を使用します。バッファは固定サイズのコンテナで、一度に1ブロックのデータを書き込むことができます。 Channel
はストリームベースのI / Oよりもかなり高速です。
Channel
を使用してファイルからデータを読み込むには、以下の手順を実行する必要があります。
-
FileInputStream
インスタンスが必要です。FileInputStream
は、チャネルを返すgetChannel()
というメソッドがあります。 - FileInputStreamの
getChannel()
メソッドを呼び出し、Channelを取得します。 - ByteBufferを作成します。 ByteBufferは固定サイズのバイトのコンテナです。
- Channelにはreadメソッドがあり、このreadメソッドの引数としてByteBufferを指定する必要があります。 ByteBufferには、読み取り専用ムードと書き込み専用ムードという2つのモードがあります。
flip()
メソッド呼び出しを使用してモードを変更できます。バッファには、位置、限界、および容量があります。固定サイズのバッファが作成されると、バッファのサイズと容量は同じサイズになり、位置はゼロから始まります。バッファにデータが書き込まれている間、その位置は徐々に増加します。モードの変更は、位置を変更することを意味します。バッファの先頭からデータを読み取るには、位置を0に設定する必要があります。 flip()メソッドは位置を変更します。 -
Channel
readメソッドを呼び出すと、データを使用してバッファがいっぱいになります。 -
ByteBuffer
からデータを読み取る必要がある場合は、バッファを反転してそのモードを書き込み専用モードに変更してから、バッファからデータを読み込み続ける必要があります。 - 読み取るデータがなくなった場合、channelの
read()
メソッドは0または-1を返します。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileChannelRead {
public static void main(String[] args) {
File inputFile = new File("hello.txt");
if (!inputFile.exists()) {
System.out.println("The input file doesn't exit.");
return;
}
try {
FileInputStream fis = new FileInputStream(inputFile);
FileChannel fileChannel = fis.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fileChannel.read(buffer) > 0) {
buffer.flip();
while (buffer.hasRemaining()) {
byte b = buffer.get();
System.out.print((char) b);
}
buffer.clear();
}
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
チャンネルを使用したファイルのコピー
私たちは、 Channel
を使ってファイルの内容をより速くコピーすることができます。これを行うには、 FileChannel
transferTo()
メソッドを使用できます。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class FileCopier {
public static void main(String[] args) {
File sourceFile = new File("hello.txt");
File sinkFile = new File("hello2.txt");
copy(sourceFile, sinkFile);
}
public static void copy(File sourceFile, File destFile) {
if (!sourceFile.exists() || !destFile.exists()) {
System.out.println("Source or destination file doesn't exist");
return;
}
try (FileChannel srcChannel = new FileInputStream(sourceFile).getChannel();
FileChannel sinkChanel = new FileOutputStream(destFile).getChannel()) {
srcChannel.transferTo(0, srcChannel.size(), sinkChanel);
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedInputStreamを使用したファイルの読み込み
BufferedInputStream
を使用してファイルを読み込むのは、基礎となる入力ストリームから読み取られたバイトを格納するための内部バッファを保持するため、 FileInputStream
よりも一般的に高速です。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileReadingDemo {
public static void main(String[] args) {
String source = "hello.txt";
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source))) {
byte data;
while ((data = (byte) bis.read()) != -1) {
System.out.println((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
チャネルとバッファを使用してファイルを書き込む
Channel
を使用してファイルにデータを書き込むには、次の手順を実行する必要があります。
- まず、
FileOutputStream
オブジェクトを取得する必要があります -
FileOutputStream
からgetChannel()
メソッドを呼び出すFileChannel
を取得します。 -
ByteBuffer
を作成し、データで埋めます - 次に、
ByteBuffer
のflip()
メソッドを呼び出して、それをFileChannel
write()
メソッドの引数として渡す必要があります - 執筆が終わったら、リソースを閉じる必要があります
import java.io.*;
import java.nio.*;
public class FileChannelWrite {
public static void main(String[] args) {
File outputFile = new File("hello.txt");
String text = "I love Bangladesh.";
try {
FileOutputStream fos = new FileOutputStream(outputFile);
FileChannel fileChannel = fos.getChannel();
byte[] bytes = text.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes);
fileChannel.write(buffer);
fileChannel.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
PrintStreamを使用してファイルを書き込む
PrintStream
クラスを使用してファイルを書き込むことができます。任意のデータ型の値を印刷できるいくつかのメソッドがあります。 println()
メソッドは新しい行を追加します。印刷が完了したら、 PrintStream
をフラッシュしなければなりません。
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.time.LocalDate;
public class FileWritingDemo {
public static void main(String[] args) {
String destination = "file1.txt";
try(PrintStream ps = new PrintStream(destination)){
ps.println("Stackoverflow documentation seems fun.");
ps.println();
ps.println("I love Java!");
ps.printf("Today is: %1$tm/%1$td/%1$tY", LocalDate.now());
ps.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
ディレクトリ内のサブディレクトリを繰り返し印刷する
public void iterate(final String dirPath) throws IOException {
final DirectoryStream<Path> paths = Files.newDirectoryStream(Paths.get(dirPath));
for (final Path path : paths) {
if (Files.isDirectory(path)) {
System.out.println(path.getFileName());
}
}
}
ディレクトリの追加
File
インスタンスから新しいディレクトリを作成するには、 mkdirs()
またはmkdir()
2つの方法のいずれかを使用する必要があります。
-
mkdir()
- この抽象パス名で指定されたディレクトリを作成します。 ( ソース ) -
mkdirs()
- この抽象パス名で指定されたディレクトリを作成します。必要な場合も存在しない親ディレクトリも含めて作成します。この操作が失敗した場合、必要な親ディレクトリのいくつかを作成できた可能性があります。 ( ソース )
注意: createNewFile()
はファイルのみ新しいディレクトリを作成しません。
File singleDir = new File("C:/Users/SomeUser/Desktop/A New Folder/");
File multiDir = new File("C:/Users/SomeUser/Desktop/A New Folder 2/Another Folder/");
// assume that neither "A New Folder" or "A New Folder 2" exist
singleDir.createNewFile(); // will make a new file called "A New Folder.file"
singleDir.mkdir(); // will make the directory
singleDir.mkdirs(); // will make the directory
multiDir.createNewFile(); // will throw a IOException
multiDir.mkdir(); // will not work
multiDir.mkdirs(); // will make the directory
標準出力/エラーのブロックまたはリダイレクト
System.err
て設計された第三者のライブラリは、望ましくない診断をSystem.out
またはSystem.err
ストリームにSystem.err
ます。推奨される解決方法は、より良いライブラリを見つけるか(オープンソースの場合)、問題を修正し、開発者にパッチを提供することです。
上記の解決策が実現できない場合は、ストリームのリダイレクトを検討する必要があります。
コマンドラインでのリダイレクト
UNIX、LinuxまたはMacOSXシステムでは、 >
リダイレクトを使用してシェルから行うことができます。例えば:
$ java -jar app.jar arg1 arg2 > /dev/null 2>&1
$ java -jar app.jar arg1 arg2 > out.log 2> error.log
最初のものは、標準出力と標準エラーを "/ dev / null"にリダイレクトします。これにより、それらのストリームに書き込まれたものはすべて破棄されます。二番目の標準出力は "out.log"に、標準エラーは "error.log"にリダイレクトされます。
リダイレクトの詳細については、使用しているコマンドシェルのドキュメントを参照してください。同様のアドバイスはWindowsに適用されます。
また、Javaアプリケーションを起動するラッパー・スクリプトまたはバッチ・ファイルでリダイレクションを実装することもできます。
Javaアプリケーション内のリダイレクション
System.setOut()
およびSystem.setErr()
を使用してJavaアプリケーション内でストリームをリダイレクトすることもできます。たとえば、次のスニペットは、標準出力と標準エラーを2つのログファイルにリダイレクトします。
System.setOut(new PrintStream(new FileOutputStream(new File("out.log"))));
System.setErr(new PrintStream(new FileOutputStream(new File("err.log"))));
出力を完全に破棄したい場合は、無効なファイル記述子に「書き込む」出力ストリームを作成することができます。これは、UNIXでは "/ dev / null"への書き込みと機能的に同等です。
System.setOut(new PrintStream(new FileOutputStream(new FileDescriptor())));
System.setErr(new PrintStream(new FileOutputStream(new FileDescriptor())));
注意: setOut
とsetErr
使い方に注意してください。
- リダイレクションは、JVM全体に影響します。
- これを行うことで、コマンドラインからストリームをリダイレクトするユーザーの能力を奪うことになります。
ZIPファイルの内容へのアクセス
Java 7のFileSystem APIは、他のファイルシステムでの操作と同じ方法で、Java NIOファイルAPIを使用してZipファイルの読み込みと追加を行うことができます。
FileSystemは使用後に適切にクローズされるべきリソースなので、try-with-resourcesブロックを使用する必要があります。
既存のファイルからの読み込み
Path pathToZip = Paths.get("path/to/file.zip");
try(FileSystem zipFs = FileSystems.newFileSystem(pathToZip, null)) {
Path root = zipFs.getPath("/");
... //access the content of the zip file same as ordinary files
} catch(IOException ex) {
ex.printStackTrace();
}
新しいファイルを作成する
Map<String, String> env = new HashMap<>();
env.put("create", "true"); //required for creating a new zip file
env.put("encoding", "UTF-8"); //optional: default is UTF-8
URI uri = URI.create("jar:file:/path/to/file.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path newFile = zipFs.getPath("/newFile.txt");
//writing to file
Files.write(newFile, "Hello world".getBytes());
} catch(IOException ex) {
ex.printStackTrace();
}