简体   繁体   English

如何锁定Excel文件以在java中读写?

[英]How to lock an Excel file for read and write in java?

I am reading a input channel using spring and whichever file comes in I am picking up the same.我正在使用 spring 读取输入通道,无论输入哪个文件,我都会读取相同的文件。 Basically the file is excel file hence I have used apache POI workbook .基本上该文件是 excel 文件,因此我使用了apache POI 工作簿 Below is the App class下面是 App 类

@SpringBootConfiguration
@EnableScheduling
@Component
public class App
{
    public static void main( String[] args ) throws IOException
    {
         SpringApplication.run(App.class, args);
    }

    @Scheduled(fixedRate = 60000)
    public static void displayDirectories () throws InvalidFormatException, IOException{
        ApplicationContext context = new ClassPathXmlApplicationContext("context.xml", App.class);
        File inDir = (File) new DirectFieldAccessor(context.getBean(FileReadingMessageSource.class)).getPropertyValue("directory");
        LiteralExpression expression = (LiteralExpression) new DirectFieldAccessor(context.getBean(FileWritingMessageHandler.class)).getPropertyValue("destinationDirectoryExpression");
        File outDir = new File(expression.getValue());
        System.out.println("Input directory is: " + inDir.getAbsolutePath());
        System.out.println("Archive directory is: " + outDir.getAbsolutePath());
        System.out.println("===================================================");
    }
}

Below are some configurations from my bean context.xml:以下是我的 bean context.xml 中的一些配置:

<file:inbound-channel-adapter id="filesIn"
    directory="file:${java.io.tmpdir}/input">
    <integration:poller id="poller" fixed-rate="60000"/>
</file:inbound-channel-adapter>

<integration:service-activator
    input-channel="filesIn" output-channel="filesOut" ref="handler" />

<file:outbound-channel-adapter id="filesOut"
    directory="file:${java.io.tmpdir}/archive" delete-source-files="true">
</file:outbound-channel-adapter>

<bean id="handler" class="com.practice.Handler" />

Below is my handler class where I am trying to acquire lock on excel file read:下面是我的处理程序类,我试图在其中获取对 excel 文件读取的锁定:

@SpringBootConfiguration
@Component
public class Handler {
    FileInputStream fileIn = null;
    FileLock lock = null;
    public File handleFile(File input) {
        try {
            fileIn = new FileInputStream(input);
            lock = fileIn.getChannel().tryLock();
            Workbook filename = WorkbookFactory.create(fileIn);
            .
            /*Some logic*/
            .
        }
        catch(Exception e){
            System.out.println("Exception occured");
            e.printStackTrace();
        }
        finally{
            try {
                lock.release();
                fileIn.close();
            } catch (IOException e) {
                System.out.println("Exception in fileclose or lock");
                e.printStackTrace();
            }
        }
        return input;
    }
}

Not implementing the lock reads my file multiple times and it process it multiple times.不实施锁定多次读取我的文件并多次处理它。 My assignment is to read the file once and process it and then archive the same.我的任务是读取文件一次并对其进行处理,然后将其存档。 When I tried implementing lock in above code I am getting an exception java.nio.channels.NonWritableChannelException .当我尝试在上面的代码中实现锁定时,我得到了一个异常java.nio.channels.NonWritableChannelException However it is suggesting me to change the same to POIFSFileSystem to resolve the same.但是,它建议我将其更改为POIFSFileSystem以解决相同的问题。 I tried the suggestions on google and they all are suggesting only for RandomAccessFile only.我在 google 上尝试了这些建议,它们都只针对 RandomAccessFile 提出建议。 I am using spring boot for the project.我正在为该项目使用弹簧靴。 Any help upon this would be much appreciated.对此的任何帮助将不胜感激。

We can lock the file, read it, modify the sheet and write it, then release the lock.我们可以锁定文件,读取它,修改工作表并写入它,然后释放锁定。 That is an important use case.这是一个重要的用例。 Every spreadsheet program works like that.每个电子表格程序都是这样工作的。

Working test case With Apache POI 4.1.1:使用 Apache POI 4.1.1 的工作测试用例:

public static void main(String[] args) throws Exception{
    File testFile = new File("src/main/resources/test.xls");
    if(! testFile.exists()){
        throw new FileNotFoundException(testFile.getAbsolutePath());
    }
    RandomAccessFile randomAccessFile = new RandomAccessFile(testFile, "rw");
    FileChannel fileChannel = randomAccessFile.getChannel();
    FileLock fileLock = fileChannel.tryLock();
    if(fileLock == null){
        throw new NullPointerException("Cannot get lock.");
    }
    boolean readOnly = false;
    POIFSFileSystem filesystem = new POIFSFileSystem(fileChannel, readOnly);
    HSSFWorkbook workbook = new HSSFWorkbook(filesystem);
    workbook.write();
    fileLock.release();
    workbook.close();
    if(!testFile.delete()){
        throw new RuntimeException("Could not delete test file.");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM