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

Java将文件移动到同名文件夹报错求助:StringIndexOutOfBoundsException

解决Java移动文件到同名文件夹的报错问题

我来帮你排查问题并实现和Windows命令相同的功能!

报错原因分析

你遇到的java.lang.StringIndexOutOfBoundsException: String index out of range: -1,是因为代码里的file.getName().indexOf(".")会在文件没有扩展名时返回-1,这时候调用substring(0, -1)就会触发索引越界异常。另外原代码还有两个逻辑问题:

  • 直接创建的new File(filename)是相对于当前工作目录的,不是你指定的DOWNLOAD_FOLDER_ROOT下的文件夹
  • 没有先判断同名文件夹是否已经存在(Windows命令是针对已有的文件夹来移动文件的)

修正后的代码实现

下面的代码完全对应Windows命令for /f %x in ('dir /ad /b') do move %x*.* %x\的逻辑:遍历目标目录下的所有文件夹,将所有以文件夹名为前缀的文件(不管有没有扩展名)移动到对应文件夹中:

private static void moveFilesToMatchingFolders() {
    File downloadRoot = new File(GlobalVariables.DOWNLOAD_FOLDER_ROOT);
    
    // 先获取所有已存在的文件夹名称,存入集合方便快速匹配
    Set<String> folderNames = new HashSet<>();
    File[] allItems = downloadRoot.listFiles();
    if (allItems == null) {
        System.out.println("目标目录不存在或无法访问");
        return;
    }
    for (File item : allItems) {
        if (item.isDirectory()) {
            folderNames.add(item.getName());
        }
    }
    
    // 遍历所有文件,匹配同名文件夹并移动
    for (File item : allItems) {
        if (!item.isDirectory()) {
            String fileName = item.getName();
            String filePrefix;
            
            // 处理有扩展名和无扩展名的情况
            int dotIndex = fileName.indexOf(".");
            if (dotIndex == -1) {
                filePrefix = fileName;
            } else {
                filePrefix = fileName.substring(0, dotIndex);
            }
            
            // 如果存在同名文件夹,执行移动
            if (folderNames.contains(filePrefix)) {
                File targetFolder = new File(downloadRoot, filePrefix);
                File targetPath = new File(targetFolder, fileName);
                // 使用renameTo时要注意:目标路径不能已有同名文件,否则会移动失败
                boolean isMoved = item.renameTo(targetPath);
                if (isMoved) {
                    System.out.println("已移动文件:" + fileName + " -> " + targetFolder.getAbsolutePath());
                } else {
                    System.out.println("移动失败:" + fileName + "(可能目标文件夹已有同名文件)");
                }
            }
        }
    }
}

代码说明

  • 先收集目标目录下所有文件夹的名称,避免重复遍历
  • 处理了无扩展名文件的情况,不会再触发索引越界异常
  • 确保目标文件夹是在DOWNLOAD_FOLDER_ROOT目录下,而不是当前工作目录
  • 添加了移动结果的日志输出,方便排查问题
  • 注意:renameTo方法在不同操作系统下的行为略有差异,如果移动失败(比如目标已有同名文件),会返回false,你可以根据需求添加覆盖或重命名的逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:40:24