簡體   English   中英

如何鎖定Excel文件以在java中讀寫?

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

我正在使用 spring 讀取輸入通道,無論輸入哪個文件,我都會讀取相同的文件。 基本上該文件是 excel 文件,因此我使用了apache POI 工作簿 下面是 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("===================================================");
    }
}

以下是我的 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" />

下面是我的處理程序類,我試圖在其中獲取對 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;
    }
}

不實施鎖定多次讀取我的文件並多次處理它。 我的任務是讀取文件一次並對其進行處理,然后將其存檔。 當我嘗試在上面的代碼中實現鎖定時,我得到了一個異常java.nio.channels.NonWritableChannelException 但是,它建議我將其更改為POIFSFileSystem以解決相同的問題。 我在 google 上嘗試了這些建議,它們都只針對 RandomAccessFile 提出建議。 我正在為該項目使用彈簧靴。 對此的任何幫助將不勝感激。

我們可以鎖定文件,讀取它,修改工作表並寫入它,然后釋放鎖定。 這是一個重要的用例。 每個電子表格程序都是這樣工作的。

使用 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