文件锁

来源:互联网 发布:淘宝卖家不同意退货 编辑:程序博客网 时间:2024/06/05 11:07

在对文件操作过程中,有时候需要对文件进行加锁操作,防止其他线程访问该文件。在NIO中提供了文件锁的功能,当一个线程文件锁定后,其他的线程是无法操作此文件的, 要想进行文件锁定的操作,则要使用FileLock类完成, 此类的对象需要依靠 FileChannel 进行实例化。

在NIO未出现之前,加锁文件可以使用RandomAccessFile类操作文件。在java.io.RandomAccessFile类的open方法,提供了参数实现独占的方式打开文件:

     

RandomAccessFile raf = new RandomAccessFile(file, "rws");

其中的“rws”参数,rw代表读取和写入,s代表了同步方式,也就是同步锁。这种方式打开的文件,就是独占方式的。

在NIO中,可以用FileChannel实例化文件锁FileLock对象的方法,加锁方法为:

RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");

FileChannel fc = raf.getChannel();

FileLock fl = fc.tryLock();

if(fl.isValid())

          System.out.println("文件已被锁定.");

下面就是一个文件加锁的例子,代码如下:

package com.javapp.ch10;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.nio.channels.FileChannel;

import java.nio.channels.FileLock;

public class FilelockTest {

         public static void main(String[] args) throws IOException,

                            InterruptedException {

                   File file = new File("D:\\test.txt");

                   RandomAccessFile raf = new RandomAccessFile(file, "rw");

                   FileChannel channel = raf.getChannel();

                   java.nio.channels.FileLock lock = channel.tryLock();

                   // 锁定60秒

                   Thread.sleep(60 * 1000);

                   // 释放

                   lock.release();

                   // close

                   channel.close();

                   raf.close();

         }

}

上面程序以独占锁的方式只允许一个线程进行文件的读/写操作,将D盘目录下的 test.txt文件锁定60秒,如果D盘目录下没有test.txt文件,可以手动创建test.txt文件。

接下来编写一个测试一个读取锁定文件的程序,代码如下:

package com.javapp.ch10;

import java.io.*;

import java.nio.channels.FileChannel;

import java.nio.channels.FileLock;

import java.nio.ByteBuffer;

public class ReadFileTest {

         public static void main(String[] args) throws Exception{

                   File file = new File("D:\\test.txt");

        FileInputStream ins = new FileInputStream(file); 

        FileChannel fIns = ins.getChannel(); 

        ByteBuffer buffer = ByteBuffer.allocate(1024); 

        while (true) { 

            buffer.clear(); 

            int r = fIns.read(buffer); 

            if(r == -1){ 

                break; 

            } 

            buffer.flip(); 

            out(buffer); 

        } 

    } 

    public static void out(ByteBuffer buffer){ 

        for (int i = 0; i < buffer.limit(); i++) { 

            System.out.print(buffer.get()); 

        } 

    } 

先运行FilelockTest类,锁定文件,然后执行ReadFileTest类,程序运行结果如下:

Exception in thread "main" java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。

         at sun.nio.ch.FileDispatcherImpl.read0(Native Method)

         at sun.nio.ch.FileDispatcherImpl.read(Unknown Source)

         at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)

         at sun.nio.ch.IOUtil.read(Unknown Source)

         at sun.nio.ch.FileChannelImpl.read(Unknown Source)

         at com.javapp.ch10.ReadFileTest.main(ReadFileTest.java:14)

原创粉丝点击