经常出现几个程序处理同一个文件的情景,比如同时更新或读取文件。应对这样的问题做出处理,否则可能发生混乱。JDK 1.4版本后,Java提供了文件锁功能,可以帮助解决这样的问题。


FileLock和FileChannel类分别在java.nio和java.nio.channels包中。输入、输出流读写文件时可以使用文件锁,以下结合RandomAccessFile类来说明文件锁的使用方法。


RandomAccessFile创建的流在读写文件时可以使用文件锁,那么只要不解除该锁,其他程序无法操作被锁定的文件。


使用文件锁的步骤如下:

1)先使用RandomAccessFile流建立指向文件的流对象,该对象的读写属性必须是rw,例如:

RandomAccessFile input = new RandomAccessFile("Main.java","rw");

2)input流调用方法getChannel()获得一个连接到底层文件的FileChannel对象(信道),例如:

FileChannel channel = input.getChannel();

3)信道调用tryLock()或lock()方法获得一个FileLock(文件锁)对象,这一过程也称做对文件加锁,例如:

FileLock lock = channel.tryLock();


文件锁对象产生后,将禁止任何程序对文件进行操作或再进行加锁。对一个文件加锁之后,如果想读、写文件必须让FileLock对象调用release()释放文件锁,例如:

lock.release();


例如,Java程序通过每次单击按钮释放文件锁,并读取文件中的一行文本,然后马上进行加锁。当Java程序运行时,用户无法用其他程序来操作被当前Java程序加锁的文件,比如用户使用Windows操作系统提供的“记事本”程序(Notepad.exe)无法保存被当前Java程序加锁的文件。


Main.java

import java.io.*;
public class Main {
    public static void main(String args[]) {
        File file = new File("Main.java");
        WindowFileLock win = new WindowFileLock(file);
        win.setTitle("使用文件锁");
    }
}


WindowFileLock.java

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WindowFileLock extends Jframe implements ActionListener {
    JTextArea text;
    JButton button;
    File file;
    RandomAccessFile input;
    FileChannel channel;
    FileLock lock;
    WindowFileLock(File f) {
        file = f;
        try {
            input = new RandomAccessFile(file,"rw");
            channel = input.getChannel();
            lock = channel.tryLock();
        }
        catch(Exception exp) {}
        text = new JTextArea();
        button = new JButton("读取一行");
        button.addActionListener(this);
        add(new JScrollPane(text),BorderLayout.CENTER);
        add(button,BorderLayout.SOUTH);
        setSize(300,400);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void actionPerformed(ActionEvent e) {
        try {
            lock.release();
            String lineString = input.readLine();
            text.append("\n"+lineString);
            lock = channel.tryLock();
            if(lineString==null)
                input.close();
        }
        catch(Exception ee) {}
    }
}


点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)