Movatterモバイル変換


[0]ホーム

URL:


S-JIS[2007-02-10/2022-03-23]変更履歴

ファイル・ディレクトリー操作

Java(JDK1.6まで)でファイルやディレクトリー関連の操作や情報を取得する方法について。
JDK1.7(Java7)以降は新しいクラスを使う。→new I/O2(nio2)[2011-07-30]

  • nio2(Path, Files)

概要

(JDK1.6以前では)ファイル・ディレクトリー関連の操作や情報保持はFileクラスで行う。[/2012-05-18]
ディレクトリ内のファイルの一覧の取得ファイルを削除するのにもFileクラスを使う。
一時ファイルを作ることも出来る。[2008-08-23]

バイナリファイルの読み書きには、基本的にInputStream・OutputStreamを用いる。[/2011-07-30]
テキストファイルの読み書きには、基本的にReader・Writerを用いる。[/2011-07-30]
プロパティーファイルの読み書きにはPropertiesが使える。
画像ファイルの読み書きにはImageIO#read()write()が使える。[2010-01-08]

(ファイルじゃないけど)出力した内容を入力に使いたい場合はパイプクラスを用いる。[2007-12-01]
ファイル内の位置を指定して読み書きしたい場合はRandomAccessFileを用いる。[/2007-12-21]
ファイルのクローズやフラッシュだけは全クラスで共通になっている。[/2011-07-30]

ファイルのコピーにはFileChannelを用いる。[/2011-07-30]
ファイル名の変更にはrenameToを呼び出す。[2011-12-22]
ファイルのロックにはFileLockを使用する。[2013-12-20]

GUIで(ドラッグして)ドロップされたファイルを受け取るにはAWTのDropTargetを用いる。
拡張子に応じて開いたり編集したりするにはAWTのDesktopを用いる。[2008-04-26]


File

ファイル名やディレクトリ名の保持は、Fileクラスで行う。(→JDK1.7ではPathを使う)

import java.io.File;

そのファイルの存在有無確認や属性の取得/変更、ディレクトリの場合はその中のファイル一覧の取得といった操作も行える。
操作の概要(他言語との比較)

ファイル名を取得する系統のメソッドでは、大抵はこのFileクラスで値を返す。

パスの区切りは、通常は環境に応じた文字を使用するが、Windowsの場合、Fileクラスは「\」でも「/」でも受け付ける。[2007-06-21]

Windowsの場合[2010-08-21]
File#toString()備考
new File("C:\\dir")C:\dir 
new File("C:\\dir\\abc.txt")C:\dir\abc.txt 
new File("C:/dir/abc.txt")C:\dir\abc.txt「/」で指定しても「\」になる。
new File("C:/dir", "abc.txt");C:\dir\abc.txt 
new File("", "C:")\C:parentに空文字列を指定した場合、頭に「\」が付く。
parentからの相対パス扱いで区切り文字が入るのだろうが…(苦笑)
new File("", "C:/dir/abc.txt")\C:\dir\abc.txt
new File((String)null, "C:")C:parentがnullだと大丈夫。
new File((String)null, "C:/dir/abc.txt")C:\dir\abc.txt
new File("\\C:\\dir", "abc.txt");C:\dir\abc.txtparentの先頭に「\」が付いていたら、その文字は削除される。

Fileインスタンスからjava.net.URLjava.net.URIを取得することが出来る。[2008-07-26]

File file = new File(parent_dir, fileName);URI uri = file.toURI();URL url = uri.toURL();//throws MalformedURLException

Fileには URLに直接変換するメソッド(File#toURL())もあるが、JDK1.6から非推奨になった。
例えば「abc%.txt」というファイルは、URIでは「%」そのものはエスケープしないと使えないので、「abc%25.txt」となるのが正しい。[2010-01-22]
しかしFile#toURL()ではそういう変換をしてくれない。File#toURI()ではそういう変換を行ってくれる。

URLURIからFileインスタンスを生成するには以下のようにする。[2008-10-14]

URL url = new URL("file:/C:/temp/");//throws MalformedURLExceptionURI uri = url.toURI();//throws URISyntaxException//JDK1.5File file = new File(uri);

一時的に使用するファイル(ファイル名)を生成するには、createTempFile()を使う。[2008-08-23]

また、そのファイルに対してdeleteOnExit()を呼び出しておくと、JavaVMの終了時に自動的に削除される。
renameTo()などでリネームして その一時ファイルが無くなっていても VM終了時にエラーになったりはしないので、事前に明示的に消しても問題なし)

FiletempDir = new File("C:/temp");File temp =File.createTempFile("zzz", ".txt", tempDir);//"C:\temp\zzz123.txt"といったファイルが作られるtemp.deleteOnExit();OutputStream os = newFileOutputStream(temp);os.write("test".getBytes());os.close();//temp.renameTo(new File(temp.getParentFile(), "zzz.txt"));

createTempFile()の第3引数(tempDir)を指定しない(あるいはnullを渡す)場合、デフォルトの場所(システムプロパティーjava.io.tmpdirで指定される場所)に作られる。


JDK1.6から、ファイルの権限(パーミッション)を変更するメソッドが追加された。[2012-05-18]
しかし、これらはUNIXではちゃんと動作するようだが、Windowsでは一部のメソッドは動作しない。

Windowsでの実行結果
メソッド戻り値動作権限確認結果
setReadable(true)true読み取り不可には出来ない。canRead()true
setReadable(false)falsetrue
setWritable(true)true書き込み権限はきちんと動作する。
書き込み不可=読み取り専用
canWrite()true
setWritable(false)truefalse
setExecutable(true)true実行不可には出来ない。canExecute()true
setExecutable(false)falsetrue

参考:More Enhancements in Java SE 6


バイナリーデータの読み書き

バイナリーデータの読み込みにはInputStream、書き込みにはOutputStreamを用いる。
入出力先の種類によって、InputStream・OutputStreamの具象クラスには いくつもの種類がある。

種類入力出力主な取得方法関連更新日
基本的な抽象クラスInputStreamOutputStream具象クラスを使用  
空データ(Java11以降)InputStream.nullInputStream()OutputStream.nullOutputStream()staticメソッド 2018-10-01
ファイルFileInputStreamFileOutputStreamコンストラクター  
データ(プリミティブ型の集合)DataInputStreamDataOutputStreamコンストラクターreadFully()2007-11-17
バイト配列byte[]ByteArrayInputStreamByteArrayOutputStreamコンストラクター  
オブジェクト(シリアライズObjectInputStreamObjectOutputStreamコンストラクター 2007-05-03
コンソール PrintStreamSystem.out使用例 
gzipファイルGZIPInputStreamGZIPOutputStreamコンストラクター  
zipファイルZipInputStreamZipOutputStreamコンストラクター  
jar・zipファイル内のファイルZipFileInputStream ZipFile  
ソケット通信SocketInputStreamSocketOutputStreamSocket  
出力した内容を読み込みPipedInputStreamPipedOutputStreamコンストラクター 2007-12-01
チェックサム(CRC)も計算するCheckedInputStreamCheckedOutputStreamコンストラクター使用例2008-12-22
後戻りが出来る入力ストリームPushbackInputStream コンストラクター 2007-12-21
他のStreamをバッファリングBufferedInputStreamBufferedOutputStreamコンストラクター  
他のStreamに委譲FilterInputStreamFilterOutputStream継承 2008-12-22
進捗ダイアログを表示するProgressMonitorInputStream コンストラクター 2009-11-08

全データの読み込み(JDK1.6以前)

JDK1.6以前でバイナリーファイルから全データをバイト配列に読み込むには、以下のようにする。

public static byte[] readBinaryFile(String fileName) {Filef = newFile(fileName);int len = (int)f.length();//ファイルの長さを取得byte[] buf = new byte[len];InputStreamis = null;try {is = newFileInputStream(f);//returnreadBinaryFull(is, len);int l =is.read(buf);System.out.println("読み込んだ長さ:" + l);} catch (Exception e) {throw new RuntimeException(e);} finally {if (is != null) try {is.close(); } catch (IOException e) {}}return buf;}

ファイルならともかく、一般的には、read()は必ずしも指定した全サイズが読めるとは限らない。InputStreamの実装依存になる。[2008-10-19]
(例えばソケット通信なら、まだ届いていないデータは読み込めず、届いている分だけread()できる)
そういった場合でも(ウェイト(待ち)が発生しても)指定したサイズを読み込みたいなら、以下のようにreadFully()が使える。

public static byte[]readBinaryFull(InputStream is, int len) throws IOException {DataInputStreamdis = newDataInputStream(is);byte[] buf = new byte[len];dis.readFully(buf);return buf;}

全データの読み込み(JDK1.7)

JDK1.7でバイナリーファイルから全データをバイト配列に読み込むには、Files.readAllBytes()を使うのが便利。[2017-09-23]

import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;
public static byte[] readAllBytes(String fileName) throws IOException {Path path = Paths.get(fileName);returnFiles.readAllBytes(path);}

全データの読み込み(JDK9)

Java9で、InputStreamに全データを読み込むメソッドが追加された。[2017-09-23]

import java.io.InputStream;import java.io.IOException;
public static byte[] readAllBytes(InputStream is) throws IOException {try (is) {return is.readAllBytes();}}

readAllBytesの中は、最初にある程度のサイズのバイト配列を用意し、足りなければ拡張し、最後にデータサイズぴったりの配列にコピーしている。
ファイルから全データを読み込むFiles.readAllBytes()はファイルサイズを取得してバイト配列を用意するので、ファイルから読み込む場合はFiles.readAllBytes()を使う方が良い。


nバイトだけ読み込むreadNBytesメソッドもある。

byte[] buf = new byte[100];int len = is.readNBytes(buf, 0, 100);
// Java11[2018-10-01]byte[] buf = is.readNBytes(100);

全データの書き込み(JDK1.6以前)

バイト配列の全データをバイナリーファイルに書き込むには、以下のようにする。

public static void writeBinaryFile(String fileName, byte[] data) {Filef = newFile(fileName);OutputStreamos = null;try {os = newFileOutputStream(f);os.write(data);} catch (Exception e) {throw new RuntimeException(e);} finally {if (os != null) try {os.close(); } catch (IOException e) {}}}

全データの書き込み(JDK1.7)

JDK1.7でバイト配列の全データをバイナリーファイルに書き込むには、Files.write()を使うのが便利。[2017-09-23]

import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;
public static void writeBinaryFile(String fileName, byte[] data) throws IOException {Path path = Paths.get(fileName);Files.write(path, data);}

データのコピー(JDK9)

Java9で、InputStreamで読み込んだ全データをOutputStreamに書き込むメソッドが追加された。[2017-09-23]

public static void transfer(InputStream is, OutputStream os) throws IOException {try (is; os) {is.transferTo(os);}}

テキストデータの読み書き

テキストデータの読み込みにはBufferedReader、書き込みにはBufferedWriterを用いる(改行付きで出力したいならPrintWriter)。
入出力先の種類によって、Reader・Writerの具象クラスにも いくつもの種類がある。

種類入力出力主な取得方法関連更新日
基本的な抽象クラスReaderWriter具象クラスを使用  
空データReader.nullReader()Writer.nullWriter()staticメソッド 2018-10-01
ファイルFileReaderFileWriterコンストラクター  
文字列(StringStringReader
(中身はString)
StringWriter
(中身はStringBuffer
コンストラクター使用例 
InputStream/OutputStreamInputStreamReaderOutputStreamWriterコンストラクター  
出力した内容を読み込みPipedReaderPipedWriterコンストラクター 2007-12-01
他のReader/WriterをバッファリングBufferedReaderBufferedWriterコンストラクター  
行番号を付けるReaderLineNumberReader コンストラクター 2009-01-01
後戻りが出来るReaderPushbackReader コンストラクター 2007-12-21
PrintStream(System.out)と似たWriter PrintWriterコンストラクター使用例2007-11-30
他のReader/Writerに委譲FilterReaderFilterWriter継承 2008-12-22

テキストファイルから読み込む例

テキストファイルから全データを読み込むには、以下のようにする(JDK1.5)。

import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.util.ArrayList;import java.util.List;
public static List<String> readTextFile(String fileName) {List<String> textList = new ArrayList<String>();Filef = newFile(fileName);InputStream is = null;Reader r = null;BufferedReader br = null;try {is = new FileInputStream(f);r  = newInputStreamReader(is, "MS932");br = newBufferedReader(r);for (;;) {String text =br.readLine();//改行コードは含まれないif (text == null) break;textList.add(text);}} catch (Exception e) {throw new RuntimeException(e);} finally {if (br != null) try {br.close(); } catch (IOException e) {}if (r  != null) try {r .close(); } catch (IOException e) {}if (is != null) try {is.close(); } catch (IOException e) {}}return textList;}

InputStreamReaderでは、キャラクターセットエンコード)を指定できる。
(キャラクターセットを指定しなかった場合は、Java17以前は環境依存、Java18以降はUTF-8になる。[2022-03-23]
InputStreamで読み込まれるバイト列が“そのエンコードである”として、UNICODEへの文字コード変換を行う。
すなわち、JavaVMの内部では文字列はUNICODEで扱われているので、テキストファイルがシフトJISなら「SJIS→UNICODE」の変換が必要になる。MS932がJavaにおけるSJISの指定だと思っていれば大体OK。

デフォルトのキャラセットでいい場合は、FileInputStreamInputStreamReaderを使わずに「r = new FileReader(f);」でよい。

Readerがネストしているときは、一番外側だけクローズしてやれば、ネストしている内側のReaderもクローズされる。[2007-05-03]
(br = new BufferedReader(new InputStreamReader(is));ならば、br.close()だけでInputStreamReaderもisもクローズされる)

上記の例ではbr・r・isの全てに対しそれぞれfinallyでクローズしており、冗長に見える。finallyでbrのクローズだけすればよいと。
しかし、もしisは作られてrを作るときに例外が発生したら、brのクローズだけではrもisもクローズされない。InputStreamReaderのエンコード指定を間違ったりしたら、例外は出るだろうな〜)
厳密には、やはりそれぞれクローズすべきだろう。


JDK1.7では以下のようにしてBufferedReaderを使用する。[2014-04-15]

import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.nio.charset.Charset;import java.nio.file.Files;import java.util.ArrayList;import java.util.List;
public static List<String> readTextFile(String fileName) {List<String> textList = new ArrayList<>();File file = new File(fileName);try (BufferedReader br =Files.newBufferedReader(file.toPath(),Charset.forName("MS932"))) {for (;;) {String text = br.readLine(); // 改行コードは含まれないif (text == null) {break;}textList.add(text);}} catch (IOException e) {throw new RuntimeException(e);}return textList;}

リソース付きtry文を使って、クローズ処理の記述を省略している。

実際には、テキストファイルの全内容を読み込んでList<String>にするには、そのものずばりのFiles.readAllLines()を使う方が便利。


JDK1.8では、BufferedReaderにlines()という(Stream<String>を返す)メソッドが追加された。[2014-04-15]
これを使うと、レコード読み込みの終了判定(readLine()のnullチェック)が不要になる。

import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.UncheckedIOException;import java.nio.charset.Charset;import java.nio.file.Files;import java.util.List;import java.util.stream.Collectors;
public static List<String> readTextFile(String fileName) {File file = new File(fileName);try (BufferedReader br =Files.newBufferedReader(file.toPath(),Charset.forName("MS932"))) {return br.lines().collect(Collectors.toList());} catch (IOException e) {throw newUncheckedIOException(e);}}

以下のような使い方をすることも出来る。

// テキストファイルの内容を1行ずつ表示する例br.lines().forEach(text-> {System.out.println(text);});

実際には、Files#lines()を使う方がBufferedReaderが出てこなくて便利。[2014-04-29]


テキストファイルに出力する例

テキストファイルに出力するには、以下のようにする(JDK1.5)。

import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.List;
public static void writeTextFile(String fileName, List<String> textList) {Filef = newFile(fileName);OutputStream os = null;Writer w = null;BufferedWriter bw = null;try {os = new FileOutputStream(f);w  = newOutputStreamWriter(os, "MS932");bw = newBufferedWriter(w);for (String text: textList) {bw.write(text);bw.newLine();//改行//bw.flush();//途中で実際に書き込みを実行したい場合はフラッシュする}} catch (Exception e) {throw new RuntimeException(e);} finally {if (bw != null) try {bw.close(); } catch (IOException e) {}if (w  != null) try {w .close(); } catch (IOException e) {}if (os != null) try {os.close(); } catch (IOException e) {}}}

OutputStreamWriterもキャラクターセットエンコード)を指定できる。(上記のMS932
(キャラクターセットを指定しなかった場合は、Java17以前は環境依存、Java18以降はUTF-8になる。[2022-03-23]
(JavaVM内部の表現である)UNICODEから“指定したキャラセット”に変換して出力される。

デフォルトのキャラセットでいい場合は、FileOutputStreamOutputStreamWriterを使わずに「w = new FileWriter(f);」でよい。

Writerがネストしているときは、一番外側だけクローズしてやれば、ネストしている内側のWriterもクローズされる。[2007-05-03]
(bw = new BufferedWriter(new OutputStreamWriter(os));ならば、bw.close()だけでOutputStreamWriterもosもクローズされる)

上記の例ではbw・w・osの全てに対しそれぞれfinallyでクローズしており、冗長に見える。finallyでbwのクローズだけすればよいと。
しかし、もしosは作られてwを作るときに例外が発生したら、bwのクローズだけではwもosもクローズされない。OutputStreamWriterのエンコード指定を間違ったりしたら、例外は出るだろうな〜)
厳密には、やはりそれぞれクローズすべきだろう。


JDK1.7では以下のようにしてBufferedWriterを使用する。[2014-04-15]

import java.io.BufferedWriter;import java.io.File;import java.nio.charset.Charset;import java.nio.file.Files;import java.nio.file.StandardOpenOption;import java.util.List;
public static void writeTextFile(String fileName, List<String> textList) {File file = new File(fileName);try (BufferedWriter bw =Files.newBufferedWriter(file.toPath(),Charset.forName("MS932"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {for (String text : textList) {bw.write(text);bw.newLine(); // 改行}} catch (Exception e) {throw new RuntimeException(e);}}

リソース付きtry文を使って、クローズ処理の記述を省略している。

実際には、List<String>をテキストファイルに書き込むには、そのものずばりのFiles.write()を使う方が便利。


パイプ

一時的にOutputStream(又はWriter)に出力し、その内容を別のInputStream(Reader)への入力としたい場合は、パイプ(Piped)の名を冠したクラスを使う。[2007-12-01]
パイプ(pipe)という名が付いているが、“UNIXDOSで標準出力の内容を次のコマンドの標準入力に渡すパイプ”とは関係ない。

パイプは、入力と出力をペアでインスタンス化する。すると、その出力インスタンスに出力した内容が、入力インスタンスで取得できる。

参考: SUGAI, ManabuさんのJava 入門 | Pipe Streams


ストリームの例:

public static void testStream() throws IOException {PipedOutputStreampos = newPipedOutputStream();PipedInputStreampis = newPipedInputStream(pos);writeStream(pos);//OutputStreamに値を出力するdumpStream(pis);//InputStreamの内容を表示する}private static voidwriteStream(OutputStream os) throws IOException {os.write(new byte[] { 0x11, 0x22, 0x33 });os.close();}private static voiddumpStream(InputStream is) throws IOException {int len = is.available();System.out.println(len);for (int i = 0; i < len; i++) {System.out.println(Integer.toHexString(is.read()));}is.close();}

なお、パイプの入出力のインスタンス生成の順番はどちらが先でもよい。
(コンストラクター内部で「相手.connect(this);」を呼び出して、指定された相手に自分を登録している為)

あと、JDK1.6からは、バッファサイズを引数に取るコンストラクターも追加されている模様。


テキストの例:

public static void testText() throws IOException {PipedWriterpw = newPipedWriter();PipedReaderpr = newPipedReader(pw);writeWriter(pw);//Writerに値を出力するdumpReader(pr);//Readerの内容を表示する}private static voidwriteWriter(Writer w) throws IOException {w.write("abc\n");w.write("def\n");w.close();}private static voiddumpReader(Reader r) throws IOException {while (r.ready()) {System.out.print((char) r.read());}r.close();}

バッファリングの例:

public static void testBuffer() throws IOException {PipedWriter pw = newPipedWriter();PipedReader pr = newPipedReader(pw);writeBuffer(pw);dumpBuffer(pr);}private static void writeBuffer(Writer w) throws IOException {PrintWriter bw = newPrintWriter(newBufferedWriter(w));bw.println("abc");bw.println("def");bw.close();}private static void dumpBuffer(Reader r) throws IOException {BufferedReader br = newBufferedReader(r);while (br.ready()) {System.out.println(br.readLine());}br.close();}

PipedWriterやPipedReaderもWriter/Readerである事に変わりは無いので、他のWriter/Reader(例えばBuffered系)のクラスでラップすることが出来る。

ただし、Piped系のクラスをBuffered系のクラスでバッファリングする場合は、書き込みのフラッシュや読み込みのブロッキングに注意を払う必要がある。

よくある実装だが、ブロッキング(永久待ち)してしまう例:

private static void writeBuffer(Writer w) throws IOException {PrintWriter bw = newPrintWriter(newBufferedWriter(w));bw.println("abc");bw.println("def");bw.flush();//bw.close();クローズしない}private static void dumpBuffer(Reader r) throws IOException {BufferedReader br = newBufferedReader(r);for(;;) {String str =br.readLine();if (str == null) break;System.out.println(str);}br.close();}

readLine()は次の入力があるまで待つので、この例ではパイプへの書き込み側でクローズしていないから(永久待ちで)無限ループになってしまう。
「readLine()がnullだったら終了する」というコーディングはよく見かけるが、このようにReaderには色々な実装(具象クラス)があるので、br.ready()(読み込めるデータがあるかどうかを判断する)を使う方が安全だと思う。

ただ、BufferedWriterを使っていてflush()しないと、br.ready()はfalseになってしまう(br.readLine()も何も読み込まない)。


ランダムアクセスファイル

ランダムアクセスというのは、ファイル内の位置を自由に(ランダムに)指定して読み書き(アクセス)できること。[2007-12-21]
ストリームはシーケンシャル(順序に従う)なので、後戻りすることが出来ない。

C言語のFILE構造体なんかはランダムアクセス。
JavaではRandomAccessFileクラスを使う。

RandomAccessFileの使用例[2007-11-30]


CloseableFlushableインターフェース

例えばInputSream・OutputSreamとRandomAccessFileは、read()・write()メソッドがそっくりに作られているが、クラス関係(インターフェースによる継承とか)としては無関係。[2007-12-21]

ただ、ファイル(ストリーム)を閉じるclose()メソッドは、JDK1.5からCloseableというインターフェースが導入され、どのクラスでもこのインターフェースを使って共通に扱えるようになった。

同様に、flush()できることを意味するFlushableというインターフェースもJDK1.5で追加された。[2008-05-17]

JDK1.7では自動的にクローズできることを表すAutoCloseableインターフェースが追加された。[2011-07-30]


ファイルのコピー

JDK1.7以降ではFiles.copy()を使ってファイルをコピーできる。[2011-07-30]
JDK1.6以前では、DOSのcopyUNIXのcpのような、直接ファイルをコピーする命令は用意されていない。[2007-05-31]
自分でファイルを読み込み、内容を別のファイルに書き込むしかない。
しかし、その為にFileChannelというクラス(java.nio.channelsパッケージのファイルチャネル)が用意されている。

FileChannelは実装がOS依存なので、自分でバイト配列に読み込んで書き込んだりするよりも速いことが期待される

import java.nio.channels.FileChannel;
public static void fileCopy(File sf, File df) {FileChannel sc = null, dc = null;try {sc = new FileInputStream(sf).getChannel();dc = new FileOutputStream(df).getChannel();dc.transferFrom(sc, 0,sc.size());//sc.transferTo(0,sc.size(),dc);} catch (IOException e) {e.printStackTrace();} finally {if (dc != null) try {dc.close(); } catch (IOException e) {}if (sc != null) try {sc.close(); } catch (IOException e) {}}}

ファイルチャネルからバッファーにデータを読み込む例
ファイルチャネルからバッファーを取得する例
ファイルチャネルを使ってファイルをロックする例

参考


ファイル名の変更

JDK1.6以前では、File#renameTo()を使ってファイルの改名を行う。[2011-12-22]
JDK1.7以降ではFiles.move()を使う。

File#renameTo()の動作は、プラットフォーム依存。つまりWindowsとUNIXでは挙動が異なることがある。
例えば、変更先のファイルが存在している場合、UNIXでは上書きするがWindowsではリネーム失敗となる。


IOException

(ファイル操作に限らず、)入出力を伴う処理(メソッド)では、IOExceptionがthrows宣言されていることが多い。[2014-03-21]

IOExceptionはチェック例外なので、catchして処理する必要がある。
ただ単に呼び出し元メソッドに再スローするだけなことも多いが、その場合はthrows宣言を書かなければならない。

import java.io.IOException;
public void readPrint(BufferedReader br)throws IOException {for(;;) {String str = br.readLine(); //throws IOExceptionif (str == null) break;System.out.println(str);}}

UncheckedIOException

JDK1.8で、非チェック例外なIOExceptionクラスが追加された。[2014-03-21]
UncheckedIOExceptionはRuntimeExceptionを継承しており、throwsで宣言しなくても呼び出し元にスローすることが出来る。

import java.io.IOException;import java.io.UncheckedIOException;
public void readPrint8(BufferedReader br) {for (;;) {try {String str = br.readLine(); //throws IOExceptionif (str == null) break;System.out.println(str);} catch (IOException e) {throw newUncheckedIOException("実験", e);}}}

UncheckedIOExceptionは(IOExceptionと継承関係があるわけではなく、)コンストラクターでIOExceptionをラップする形式になっている。

で、UncheckedIOException#getCause()は(共変戻り値型により)ちゃんとIOExceptionを返すようになっている。


Java目次へ戻る /新機能へ戻る /技術メモへ戻る
メールの送信先:ひしだま

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


[8]ページ先頭

©2009-2025 Movatter.jp