Java FileLock for Reading and Writing

后端 未结 3 1318
庸人自扰
庸人自扰 2020-12-03 04:53

I have a process that will be called rather frequently from cron to read a file that has certain move related commands in it. My process needs to read and write to this dat

3条回答
  •  悲&欢浪女
    2020-12-03 05:47

    I wrote a test program and bash commands to confirm the effectivity of the file lock:

    import java.io.File;
    import java.io.RandomAccessFile;
    import java.nio.channels.FileLock;
    
    public class FileWriterTest
    {
        public static void main(String[] args) throws Exception
        {
            if (args.length != 4)
            {
                System.out.println("Usage: FileWriterTest    ");
                System.exit(1);
            }
    
            String filename = args[0];
            String data = args[1];
            int sleep = Integer.parseInt(args[2]);
            boolean enableLock = Boolean.parseBoolean(args[3]);
    
            try (RandomAccessFile raFile = new RandomAccessFile(new File(filename), "rw"))
            {
                FileLock lock = null;
                if (enableLock)
                {
                    lock = raFile.getChannel().lock();
                }
    
                Thread.sleep(sleep);
                raFile.seek(raFile.length());
                System.out.println("writing " + data + " in a new line; current pointer = " + raFile.getFilePointer());
                raFile.write((data+"\n").getBytes());
    
                if (lock != null)
                {
                    lock.release();
                }
            }
        }
    }
    

    Run with this bash command to check it works:

    for i in {1..1000}
    do
    java FileWriterTest test.txt $i 10 true &
    done
    

    You should see the writing only happening once every 10ms (from the outputs), and in the end all numbers to be present in the file.

    Output:

    /tmp wc -l test.txt
    1000 test.txt
    /tmp
    

    The same test without the lock shows data being lost:

    for i in {1..1000}
    do
    java FileWriterTest test.txt $i 10 false &
    done
    

    Output:

    /tmp wc -l test.txt
    764 test.txt
    /tmp
    

    It should be easy to modify it to test the tryLock instead.

提交回复
热议问题