You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java处理Excel文件执行移动操作时抛出java.nio.file.FileSystemException异常

问题修复方案

错误根因

你的代码执行顺序有问题:你先通过new FileInputStream(file)打开了目标Excel文件的输入流,此时该文件已经被当前Java进程持有锁,后续再调用Files.move移动文件时,就会触发文件被其他进程占用的报错。
你之前只做入库逻辑没问题,是因为不需要移动文件,不存在操作被文件锁拦截的场景。

修复方案

调整操作顺序即可,这里推荐两种可行方案:

方案一:先完成文件读取、入库全流程,关闭流后再移动文件

使用try-with-resources自动管理流资源,避免手动关流遗漏导致的资源泄漏,修正后的代码如下:

public static void acceptExcellFileAndInsertToDatabase(File file) {
    String phoneNumber = "";
    String textMessage = "";
    // 用try-with-resources自动关流,执行完括号内逻辑后会自动释放文件占用
    try (FileInputStream excelFile = new FileInputStream(file)) {
        Workbook workbook = new XSSFWorkbook(excelFile);
        Sheet datatypeSheet = workbook.getSheetAt(0);
        Iterator<Row> iterator = datatypeSheet.iterator();
        while (iterator.hasNext()) {
            Row currentRow = iterator.next();
            Iterator<Cell> cellIterator = currentRow.iterator();
            while (cellIterator.hasNext()) {
                Cell currentCell = cellIterator.next();
                if (currentCell.getCellTypeEnum() == CellType.NUMERIC) {
                    phoneNumber = NumberToTextConverter.toText(currentCell.getNumericCellValue());
                } else if (currentCell.getCellTypeEnum() == CellType.STRING) {
                    textMessage = String.valueOf(currentCell.getStringCellValue());
                }
            }
        }
        insertExcellFileToDb(phoneNumber, textMessage);
        System.out.println(phoneNumber + " " + textMessage);
        // 流已经自动关闭,文件占用释放,此时再移动文件
        Path sourcePath = Paths.get(String.valueOf(file));
        Path targetPath = Paths.get("C:\\Users\\anar.memmedov\\Desktop\\ko\\" + sourcePath.getFileName());
        Files.move(sourcePath, targetPath);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

方案二:先移动文件,再读取移动后的文件做入库操作

如果你的业务要求优先归档文件,就可以先移动文件,再从目标路径读取文件处理:

public static void acceptExcellFileAndInsertToDatabase(File file) {
    try {
        String phoneNumber = "";
        String textMessage = "";
        Path sourcePath = Paths.get(String.valueOf(file));
        Path targetPath = Paths.get("C:\\Users\\anar.memmedov\\Desktop\\ko\\" + sourcePath.getFileName());
        // 先移动文件,此时还没打开文件,不存在占用
        Files.move(sourcePath, targetPath);
        // 读取移动后的目标路径的文件
        try (FileInputStream excelFile = new FileInputStream(targetPath.toFile())) {
            Workbook workbook = new XSSFWorkbook(excelFile);
            Sheet datatypeSheet = workbook.getSheetAt(0);
            Iterator<Row> iterator = datatypeSheet.iterator();
            while (iterator.hasNext()) {
                Row currentRow = iterator.next();
                Iterator<Cell> cellIterator = currentRow.iterator();
                while (cellIterator.hasNext()) {
                    Cell currentCell = cellIterator.next();
                    if (currentCell.getCellTypeEnum() == CellType.NUMERIC) {
                        phoneNumber = NumberToTextConverter.toText(currentCell.getNumericCellValue());
                    } else if (currentCell.getCellTypeEnum() == CellType.STRING) {
                        textMessage = String.valueOf(currentCell.getStringCellValue());
                    }
                }
            }
            insertExcellFileToDb(phoneNumber, textMessage);
            System.out.println(phoneNumber + " " + textMessage);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

额外说明

该问题本质是单进程内的资源占用顺序问题,使用多线程完全解决不了,反而会增加不必要的复杂度,不需要做这方面的尝试。

内容的提问来源于stack exchange,提问作者iwritecomeinmymind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 09:09:01