众所周知,Java中锁的概念是非常重要的,锁可以保证资源的安全可控,恰当使用锁即可使得资源高效利用,又能保证线程的安全访问,编程中在读取文件的时候常常碰到文件锁的使用,本文简单阐述文件锁在Java中的使用范例,代码仅供参考。
FileLock文件锁
public abstract class FileLock implements AutoCloseable {……}
“Locks are associated with files, not channels. Use locks to coordinate with external processes, not between threads in the same JVM.”
public static String readChannel(final File file, final String encoding) {
final StringBuilder builder = new StringBuilder();
FileLock fileLock = null;
// FileInputStream will throws java.nio.channels.NonWritableChannelException
try(RandomAccessFile ra = new RandomAccessFile(file, "rw"); FileChannel fileChannel = ra.getChannel())
{
do
{
fileLock = fileChannel.tryLock();
} while (null == lock);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while ((fileChannel.read(buffer)) != -1)
{
buffer.flip(); // Flip buffer
builder.append(Charset.forName(setCharset(encoding)).decode(buffer));
buffer.clear();
}
// release resource
fileLock.release();
} catch (IOException e)
{
e.printStackTrace();
}
return builder.toString();
}
public static void writeChannel(final File file, final String data, final String encoding) {
try(FileOutputStream fos = new FileOutputStream(file);
FileChannel fileChannel = fos.getChannel();
FileLock fileLock = fileChannel.lock()/*无参lock()为独占锁*/)
{
fileChannel.write(ByteBuffer.wrap(data.getBytes(setCharset(encoding))));
} catch (IOException e)
{
e.printStackTrace();
}
}
对于这个锁有如上表述,明确指出此锁用于不同JVM之间的进程来限制文件的读写,而非多线程之间的读写。那么多线程之间读写锁用哪个呢?答案是ReadWriteLock
ReadWriteLock读写锁
public interface ReadWriteLock{……}
顾名思义,此锁作为读写锁用于相同JVM的线程间读写文件操作。而此锁的实现,诸如:可重入的读写锁(ReentrantReadWriteLock)是比较常用的。
public class FileLockUtil {
private final static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final static String DEFAULT_ENCODING = "UTF-8";
public static void write(final File file, final String data, final String encoding) {
lock.writeLock().lock();
try(OutputStreamWriter writer = new OutputStreamWriter(
new BufferedOutputStream(new FileOutputStream(file)), Charset.forName(setCharset(encoding))))
{
writer.write(data);
writer.flush();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
lock.writeLock().unlock();
}
}
public static String read(final File file, final String encoding) {
lock.readLock().lock();
final StringBuilder builder = new StringBuilder();
try(InputStreamReader reader = new InputStreamReader(
new BufferedInputStream(new FileInputStream(file)), Charset.forName(setCharset(encoding))))
{
char[] buffer = new char[1024];
int len = -1;
while ((len = reader.read(buffer)) != -1)
{
builder.append(buffer, 0, len);
}
} catch (IOException e)
{
e.printStackTrace();
} finally
{
lock.readLock().unlock();
}
return builder.toString();
}
private static String setCharset(final String encoding) {
return Optional.ofNullable(encoding).orElse(DEFAULT_ENCODING);
}
}
文章末尾固定信息
继续阅读
我的微信
微信号已复制
微信公众号
分享IT信息技术、北海生活的网站。提供北海本地化的信息技术服务。














