【进阶】-Java读写文件锁

路飞
路飞
管理员
43
文章
评论字数 507阅读1分41秒

众所周知,Java中锁的概念是非常重要的,锁可以保证资源的安全可控,恰当使用锁即可使得资源高效利用,又能保证线程的安全访问,编程中在读取文件的时候常常碰到文件锁的使用,本文简单阐述文件锁在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);
	}
}

继续阅读
weinxin
微信公众号
分享IT信息技术、北海生活的网站。提供北海本地化的信息技术服务。
 最后更新:2020-1-21
路飞
  • 本文由 路飞 发表于2019年9月23日 12:36:37
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定