likes
comments
collection
share

《JAVA筑基》第45天:输入、输出系列5-文件锁定功能

作者站长头像
站长
· 阅读数 53

PC端主页可联系我,欢迎问题咨询和技术交流!

零、前言

我的学习策略很简单,题海策略+ 费曼学习法。如果能把这100题都认认真真自己实现一遍,那意味着 JAVA语言 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。

一、题目描述-文件锁定功能

1、题目

在操作文件时,有时会遇到一个问题:该文件已经被另一个程序占用,打开失败。这是因为另一个程序在编辑此文件。

实现:对D盘的xiaoxuzhu.txt文件进行锁定1分钟,1分钟后解锁。

二、解题思路

创建一个类:EncryptInput

使用FileChannel类的tryLock()获取文件锁定,如果没获取到文件锁,会返回null。可以通过这个返回值判断是否有没有被锁定。

FileLock 一般都是从FileChannel 中获取

FileLock 是文件锁,它能保证同一时间只有一个进程(程序)能够修改它,或者都只可以读,这样就解决了多进程间的同步文件,保证了安全性。但是需要注意的是,它进程级别的,不是线程级别的,他可以解决多个进程并发访问同一个文件的问题,但是它不适用于控制同一个进程中多个线程对一个文件的访问。这也是为什么它叫做 多进程文件锁,而不是 多线程文件锁

三、代码详解

EncryptInput类

package com.xiaoxuzhu;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileLock;

/**
 * Description:
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改记录:
 * 修改后版本	        修改人		修改日期			修改内容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class EncryptInput {

    @SuppressWarnings("unused")
    public static void fileLock(String file) {
        FileOutputStream fous = null; // 创建FileOutputStream对象
        FileLock lock = null; // 创建FileLock对象
        try {
            fous = new FileOutputStream(file,true); // 实例化FileOutputStream对象
           
            lock = fous.getChannel().tryLock(); // 获取文件锁定
            if(lock==null){
                //不需要处理了
                return;
            }
            String str = "虚竹哥好帅";
            IoUtil.write(fous, CharsetUtil.UTF_8,Boolean.FALSE,str);
            Thread.sleep(60 * 1000); // 线程锁定1分钟
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(lock!=null){
                    lock.release();
                }
                System.out.println("文件解锁");
                IoUtil.close(fous);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("对 D://xiaoxuzhu1.txt 的文件进行锁定");
        // 创建文件对象
        String file = "D://xiaoxuzhu1.txt";
        // 调用文件锁定方法
        fileLock(file); 
    }
}

EncryptInput2类:测试是否锁定了文件

package com.xiaoxuzhu;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileLock;

/**
 * Description:
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改记录:
 * 修改后版本	        修改人		修改日期			修改内容
 * 2022/5/3.1	    xiaoxuzhu		2022/5/3		    Create
 * </pre>
 * @date 2022/5/3
 */

public class EncryptInput2 {

    @SuppressWarnings("unused")
    public static void fileLock(String file) {
        FileOutputStream fous = null; // 创建FileOutputStream对象
        FileLock lock = null; // 创建FileLock对象
        try {
            fous = new FileOutputStream(file,true); // 实例化FileOutputStream对象
           
            lock = fous.getChannel().tryLock(); // 获取文件锁定
            if(lock==null){
                //不需要处理了
                System.out.println("没有获取到文件锁,此文件已被锁定");
                return;
            }
            String str = "虚竹哥57好帅";
            IoUtil.write(fous, CharsetUtil.UTF_8,Boolean.FALSE,str);
            Thread.sleep(60 * 1000); // 线程锁定1分钟
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(lock!=null){
                    lock.release();
                }
                IoUtil.close(fous);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("对 D://xiaoxuzhu1.txt 的文件进行锁定");
        // 创建文件对象
        String file = "D://xiaoxuzhu1.txt";
        // 调用文件锁定方法
        fileLock(file); 
        
    }
}

《JAVA筑基》第45天:输入、输出系列5-文件锁定功能

《JAVA筑基》第45天:输入、输出系列5-文件锁定功能

《JAVA筑基》第45天:输入、输出系列5-文件锁定功能

《JAVA筑基》第45天:输入、输出系列5-文件锁定功能

多学一个知识点

new一个FileOutputStream对象时,如果file文件内容本身存在,会清空数据。

 new FileOutputStream(file); 

如果不要清空数据,可以使用

= new FileOutputStream(file,true);