上读锁,测试写
场景:Java程序上读锁,其他程序不申请锁直接写
结果:写入失败,但是会清空文件
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.SeekableByteChannel;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.Arrays;public class FileChannelDemo {public static void writeFile(String filepath) throws IOException {Path path = Paths.get(filepath);if (Files.notExists(path)) {if (Files.notExists(path.getParent())) {Files.createDirectories(path.getParent());}Files.createFile(path);}FileOutputStream outputStream = new FileOutputStream(path.toFile());FileChannel fileChannel = outputStream.getChannel();ByteBuffer byteBuffer = ByteBuffer.wrap("hello world".getBytes());fileChannel.write(byteBuffer);// 重新拿到内容byteBuffer.rewind();byteBuffer.position(5);byte[] bs = " Tom's".getBytes();byte[] newBs = Arrays.copyOf(bs, bs.length + byteBuffer.remaining());byteBuffer.get(newBs, bs.length, byteBuffer.remaining());byteBuffer = ByteBuffer.wrap(newBs);fileChannel.position(5);fileChannel.write(byteBuffer);fileChannel.close();outputStream.close();}}
import java.io.FileInputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;public class FileLockDemo {public static final String FILEPATH = "nio-demo/lock.txt";public static void main(String[] args) throws IOException, InterruptedException {FileChannelDemo.writeFile(FILEPATH);FileInputStream inputStream = new FileInputStream(FILEPATH);FileChannel channel = inputStream.getChannel();FileLock lock = channel.lock(0, Integer.MAX_VALUE, true);System.out.println("文件已上锁");Thread.sleep(10000);ByteBuffer buffer = ByteBuffer.allocateDirect(32);channel.read(buffer);buffer.flip();byte[] bs = new byte[buffer.remaining()];buffer.get(bs);System.out.println("文件读取完成: " + new String(bs));lock.release();System.out.println("锁已释放");channel.close();inputStream.close();}}
import java.io.FileOutputStream;import java.io.IOException;public class FileNoLockWriteDemo {public static void main(String[] args) throws IOException {System.out.println("准备打开文件");FileOutputStream outputStream = new FileOutputStream(FileLockDemo.FILEPATH);byte[] bs = "This is a joke".getBytes();System.out.println("准备写入");outputStream.write(bs);System.out.println("写入完成");}}
java异常信息:
准备打开文件准备写入Exception in thread "main" java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。at java.io.FileOutputStream.writeBytes(Native Method)at java.io.FileOutputStream.write(FileOutputStream.java:313)at com.semonx.demoset.io.nio.FileNoLockWriteDemo.main(FileNoLockWriteDemo.java:13)
尝试过使用Notepad++来写文件,结果是一样的:写入失败,文件被清空
上写锁,测试写
场景:Java程序上写锁,其他程序不上锁
结果:在写的过程中,其他进程来写,有可能造成文件数据被破坏
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class FileWriteLockDemo {
public static final String FILEPATH = "nio-demo/lock.txt";
public static void main(String[] args) throws IOException, InterruptedException {
FileChannelDemo.writeFile(FILEPATH);
FileOutputStream outputStream = new FileOutputStream(FILEPATH);
FileChannel channel = outputStream.getChannel();
FileLock lock = channel.lock();
System.out.println("文件已上锁");
channel.write(ByteBuffer.wrap("write lock!\r\n".getBytes()));
Thread.sleep(10000);
channel.write(ByteBuffer.wrap("write lock!".getBytes()));
lock.release();
System.out.println("锁已释放");
channel.close();
outputStream.close();
}
}
推测
文件锁和普通的内存锁应该差不多,只有正确地使用锁,才能保证临界资源的安全性。如果有进程不申请锁就进行访问,是有可能破坏掉文件的。
