首页 > 解决方案 > Java - 以编程方式检查文件名中的无效字符

问题描述

最近,我们有人上传了一个名称中包含非法字符(双连字符)的文件,导致无法重新下载该文件。在这种情况下,文件名是
Some name -- some other information

对于上传,通过获取作为业务规则的原始文件名来设置文件名。

file.setFileName(file.getFile().getOriginalFilename());

这导致双连字符变成两个倒置的问号,无论出于何种原因,都导致无法从服务器检索文件。

我想知道是否有一种编程解决方案来检查原始文件名是否存在这种情况。

为了透明起见,这里是上传文件的代码:

 public void saveOpcertCeuFile(OpcertCeuFileUpload file) {
        UmdContact user = secUtilService.getActiveUser();
        String username = user.getEmail();
        Date now = new Date();

        file.setCreatedTs(now);
        file.setLastUpdatedTs(now);
        file.setCreatedBy(username);
        file.setLastUpdatedBy(username);
        file.setFileName(file.getFile().getOriginalFilename());
        file.setIsApproved(Boolean.FALSE);
        file.setIsDeleted(Boolean.FALSE);

        try {
            file.setByteContents(file.getFile().getBytes());
        } catch (Exception ex) {
            log.info(ex);
            throw new RuntimeException(ex);
        }
        dao.insertOpcertCeuFileUpload(file);

        Path path = this.getOptcertCeuFilePath(file);
        String configF = envService.getServerUrl();
        file.setFilePath(String.valueOf(path));
        dao.updateOpcertCeuFilePath(file);

        try {
            File file1 = path.toFile();
            file1.getParentFile().mkdirs();
            Files.write(path, file.getByteContents(), StandardOpenOption.CREATE_NEW);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

标签: javafile

解决方案


你的文件系统,你的规则

如果您想存储文件,请根据您想要的任何规则命名它们,但不要让用户指定名称。会不会有名字冲突?文件名是否包含无效字符?你永远不会知道。

因此,请使用您自己的命名约定。但是您说有一些业务规则迫使您保留原始文件名。所以就在另一个地方做吧。

例如,您获取文件Hello--World.txt,使用20201124-000001.uploaded文件系统上的名称,然后将文件名存储在一些元数据中Hello--World.txt。当有人想要下载该文件名时,只需提供原始文件名作为下载。通过这种方式,您可以将元数据与您的文件名相关联,但可以确保系统安全。

您的代码中的示例:

// Name on filesystem.
file.setFileName(date + "-" + orderingNumberForDate(date) + ".uploaded");     

// Name in the metadata (text or db)
file.setOriginalFileName(file.getFile().getOriginalFilename()); 

推荐阅读