スレッド間の排他制御には使えません(OverlappingFileLockException がスローされる)
String FILE_NAME = "lockfile.lck";
try ( FileChannel fc = FileChannel.open( Paths.get( FILE_NAME ),
StandardOpenOption.CREATE, StandardOpenOption.WRITE )) {
FileLock lock = fc.lock();
if( lock != null ) {
try {
System.out.println( "Get lock !" );
for( int ii=1; ii<=7; ii++ ) {
try {
Thread.sleep( 1000 );
System.out.print( ii );
} catch( InterruptedException ex ) {}
}
System.out.println( "" );
} finally {
System.out.println( "Lock release" );
lock.release();
}
} else {
System.out.println( "Can't get lock ..." );
}
}
String FILE_NAME = "lockfile.lck";
try ( FileChannel fc = FileChannel.open( Paths.get( FILE_NAME ),
StandardOpenOption.CREATE, StandardOpenOption.WRITE )) {
FileLock lock = fc.tryLock();
if( lock != null ) {
try {
System.out.println( "Get lock !" );
for( int ii=1; ii<=7; ii++ ) {
try {
Thread.sleep( 1000 );
System.out.print( ii );
} catch( InterruptedException ex ) {}
}
System.out.println( "" );
} finally {
System.out.println( "Lock release" );
lock.release();
}
} else {
System.out.println( "Can't get lock ..." );
}
}
String FILE_NAME = "lockfile.lck";
try ( FileChannel fc = FileChannel.open( Paths.get( FILE_NAME ),
StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.APPEND )) {
FileLock lock = fc.lock();
if( lock != null ) {
try {
System.out.println( "Get lock !" );
val cs = Charset.forName("UTF-8");
fc.write(cs.encode("hoge"));
fc.write(cs.encode("\r\n"));
} catch(Exception ex ) {
ex.printStackTrace();
} finally {
System.out.println( "Lock release" );
lock.release();
}
} else {
System.out.println( "Can't get lock ..." );
}
}
BufferedReader reader = BufferedReader( InputStreamReader( FileInputStream( "sjis.txt" ), Charsets.UTF_8 ));
String line = null;
while(( line = reader.readLine()) != null ) {
System.out.println( line );
}
ByteBuffer bbuf = ByteBuffer.allocateDirect( 4096 );
CharBuffer cbuf = CharBuffer.allocate( 4096 )
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
decoder.onMalformedInput( CodingErrorAction.REPLACE );
FileChannel fc = FileChannel.open( Paths.get( "sjis.txt" ), StandardOpenOption.READ );
try {
int len;
while(( len = fc.read( bbuf )) >= 0 ) {
bbuf.flip();
CoderResult rs = decoder.decode( bbuf, cbuf, false )
// CodingErrorAction.REPLACE を指定していると、実際にはスローされない
if( rs.isMalformed() || rs.isUnmappable()) rs.throwException()
cbuf.flip();
System.out.print( cbuf );
bbuf.compact();
}
fc.close();
} finally {
fc.close();
}
次の環境で発生
java.nio.file.Files.move(Path source, Path target, CopyOption… options) を使ってリネームする時、options に次のどちらか、または両方を指定していると発生。
(Sambaサーバ側のログに rename コマンドの実行履歴は出力されていない。
つまりサーバでは rename されたと認識していない模様。。)
どちらも指定せず実行すると、確実にリネームされた。
※共有フォルダを別の Mac でもマウントし、出力されたファイルをエディタで開いて閉じた後に、同名のファイルにリネームしようとすると、発生しやすい。別の Mac でマウントしなかったら発生しない。
(回避策)
options 付きでリネームしても、リネーム元のファイルが残っている場合は、options なしでリネームする。