Search code examples
javaapache-poifilelock

Locking an XLSX file for reading and writing with FileInputStream, FileOutputStream, and RandomAccessFile


I have an excel that I want to be locked when each forked process is reading and writing to it. Apache poi requires me to use FileInputStream and FileOutputStream for reading and writing to that file, but all the examples I've seen for locking a file for reading and writing use RandomAccessFile for this, but when I do this, when I call workbook.write(os); I get an org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException and the excel becomes corrupted. Here is some of the code:

try {
        RandomAccessFile raf = new RandomAccessFile(path,"rw");
        FileChannel channel = raf.getChannel();
        FileLock lock = channel.lock(0L,Long.MAX_VALUE,true);

        FileInputStream is = new FileInputStream(path);
        XSSFWorkbook workbook = new XSSFWorkbook(is);
        XSSFSheet sheet = workbook.getSheet(env.toUpperCase());

        Iterator<Row> rowIterator = sheet.iterator();
        //skip headers
        rowIterator.next();
        while (rowIterator.hasNext())
        {
            //reading and editing values in excel
        }

        is.close();

        FileOutputStream os = new FileOutputStream(path);   
        workbook.write(os);
        workbook.close();
        os.close();    

        lock.release();
        channel.close();
        raf.close();

    }

Solution

  • Don't use RandomAccessFile, FileChannel and FileLock on your actual shared file, try to create and lock a separate dummy file instead. This way the process that succeeds won't see unusual locks or other activity on the Excel file.