Java 文件名验证

Java 文件名验证,java,string,java-8,java-stream,Java,String,Java 8,Java Stream,我每分钟在一个线程中验证目录中的多个文件。 目前我正在使用下面的函数,效果很好。 我的问题是,我是否可以重写这个方法以运行得更快(java8?),并且希望更短 public boolean validateFile(String fileName) { fileName = fileName.substring(0, fileName.lastIndexOf('.')); String[] values = fileName.split("_"); if (values.

我每分钟在一个线程中验证目录中的多个文件。 目前我正在使用下面的函数,效果很好。 我的问题是,我是否可以重写这个方法以运行得更快(java8?),并且希望更短

public boolean validateFile(String fileName) {
    fileName = fileName.substring(0, fileName.lastIndexOf('.'));
    String[] values = fileName.split("_");
    if (values.length == 4) {
        if(!values[1].matches("0*")) {
            if(!fileName.contains(" ")) {
                if(values[3].equals("PASS") || values[3].equals("FAIL")) {
                    return true;
                }
            }
        }
    }
    return false;
}
验证规则:

  • 文件名不能包含任何空白字符
  • 文件名拆分器始终为\u字符
  • 值[1]不能仅包含零(0)。它必须有12位数字
  • 值[3]必须包含“通过”或“失败”
  • 数组值[]长度必须始终为4

  • 您可以在类似这样的东西上使用文件名示例来运行和分叉这段代码,只需将分支转换为java-8即可。可能更容易阅读,但不会更快

     return Optional.ofNullable("test") // your fileName
                .filter(x -> !x.contains(" "))
                .map(x -> x.substring(0, x.lastIndexOf(".")))
                .map(x -> x.split("_"))
                .filter(arr -> arr.length == 4)
                .filter(arr -> !arr[1].matches("0*"))
                .filter(arr -> arr[3].equals("PASS") || arr[3].equals("FAIL"))
                .isPresent();
    

    类似这样的东西—只是将分支简单地转换为java-8。可能更容易阅读,但不会更快

     return Optional.ofNullable("test") // your fileName
                .filter(x -> !x.contains(" "))
                .map(x -> x.substring(0, x.lastIndexOf(".")))
                .map(x -> x.split("_"))
                .filter(arr -> arr.length == 4)
                .filter(arr -> !arr[1].matches("0*"))
                .filter(arr -> arr[3].equals("PASS") || arr[3].equals("FAIL"))
                .isPresent();
    
    即使您的答案更具表达力,但我认为您也可以将整个
    regex
    分解为若干部分,以使其更清晰。例如:

    private static final String PREFIX = "\\w+";
    private static final String DIGIT12 = "(?:[1-9]\\d{11}|0\\d{11})";
    private static final String TIMESTAMP = "[1-9]\\d{11}";
    private static final String STATUS = "(?:PASS|FAIL)";
    private static final String EXTENSION = "\\p{Alpha}+";
    
    private static final String FILENAME_REGEX =
            format("%s_%s_%s_%s\\.%s", PREFIX, DIGIT12, TIMESTAMP, STATUS, EXTENSION);
    
    private boolean validateFile(String fileName) {
        return fileName.matches(FILENAME_REGEX);
    }
    
    即使您的答案更具表达力,但我认为您也可以将整个
    regex
    分解为若干部分,以使其更清晰。例如:

    private static final String PREFIX = "\\w+";
    private static final String DIGIT12 = "(?:[1-9]\\d{11}|0\\d{11})";
    private static final String TIMESTAMP = "[1-9]\\d{11}";
    private static final String STATUS = "(?:PASS|FAIL)";
    private static final String EXTENSION = "\\p{Alpha}+";
    
    private static final String FILENAME_REGEX =
            format("%s_%s_%s_%s\\.%s", PREFIX, DIGIT12, TIMESTAMP, STATUS, EXTENSION);
    
    private boolean validateFile(String fileName) {
        return fileName.matches(FILENAME_REGEX);
    }
    


    由于您的代码可以正常工作,并且您只是在寻找一种改进的方法,因此我认为这个问题应该在.Regular expression?上解决,因为它属于打开,所以我投票将这个问题作为主题外的问题关闭。上面的代码没有验证文件名格式的所有规则。此外,扫描文本以验证文件名几乎肯定会比读取目录中文件的时钟时间要短。尝试优化此方法不太可能影响执行时间。您可以将所有条件与
    &&
    组合,而不是嵌套
    if
    语句。然后,如果(组合条件)返回true,则替换剩余的
    ;[否则]返回false与单个
    返回组合条件。由于您的代码正常工作,并且您只是在寻找改进的方法,我认为这个问题更适合于。正则表达式?我投票将这个问题作为主题外的问题关闭,因为它属于打开。以上代码没有验证文件名格式的所有规则。此外,扫描文本以验证文件名几乎肯定会比读取目录中文件的时钟时间要短。尝试优化此方法不太可能影响执行时间。您可以将所有条件与
    &&
    组合,而不是嵌套
    if
    语句。然后,如果(组合条件)返回true,则替换剩余的
    ;[否则]返回false与单个
    返回组合条件。似乎可选的更合适。似乎可选的更合适。@nanomader94是的,我使用了静态导入来代替,:)顺便说一句,我选择第一个答案,因为这不是我的文件名示例的现成答案,我没有时间更正它。不过,谢谢你。@nanomader94没关系。一点也不。这是因为您的示例违反了规则:“它必须有12位数”,但在您的示例中只有11位数。:)你完全正确。在ideone上,最后一个文件名示例和第一个有效的文件名示例有11位数字。我的错。@nanomader94是的,我用静态导入来代替,:)顺便说一句,我选择第一个答案是因为这一个对于我的文件名示例来说不是现成的,我没有时间来纠正它。不过,谢谢你。@nanomader94没关系。一点也不。这是因为您的示例违反了规则:“它必须有12位数”,但在您的示例中只有11位数。:)你完全正确。在ideone上,最后一个文件名示例和第一个有效的文件名示例有11位数字。我的错。