检查文件内容中缺少哪个参数

Checking which parameter is missing from file content

我有一个 TransferReader class 它使用以下形式读取包含从银行帐户到另一个帐户的转账数据的文件:

SenderAccountID,ReceiverAccountID,Amount,TransferDate

"473728292,474728298,1500.00,2019-10-17 12:34:12"(未修改的字符串)

假设文件在读取前被修改,导致上面提到的参数之一丢失,我想检查哪些参数丢失了。

"474728298,1500.00,2019-10-17 12:34:12"(修改后的字符串)

我正在使用 BufferedReader 读取每一行,然后使用 [=33= 将每个元素拆分为 String[] ](",") 作为分隔符。

如前所述,因为 发件人帐户 ID收件人帐户 ID 在一条记录中彼此紧挨着,没有真正的方法知道哪个 ID 可能丢失,除非分隔符保留在它的位置以指示 Null 值。然而,有可用的机制来确定它确实是缺少的两个中的一个,需要通过用户审查来执行哪个,即便如此,可能 还不够好.其他记录列字段如 AmountTransfer Date可以很容易地验证,或者如果缺失可以牵涉到特定的 文件数据状态日志 .

下面的代码将读取数据文件(名为 Data.csv)并将潜在的数据行(记录)错误记录到列表界面对象中,该对象在控制台中迭代并显示 Window 读取完成时。还有一些小的辅助方法。这是代码:

private void checkDataFile(String filePath) {
    String ls = System.lineSeparator();
    List<String> validationFailures = new ArrayList<>();
    StringBuilder sb = new StringBuilder();

    // 'Try With Resources' used here to auto-close reader.
    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
        String line;
        int lineCount = 0;
        // Read the file line-by-line.
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            lineCount++;
            if (lineCount == 1 || line.equals("")) {
                continue;
            }
            sb.delete(0, sb.capacity()); // Clear the StringBuilder object

            // Start the Status Log
            sb.append("File Line Number: ").append(lineCount)
                    .append(" (\"").append(line).append("\")").append(ls);
            // Split line into an Array based on a comma delimiter
            // reguardless of the delimiter's spacing situation.
            String[] lineParts = line.split("\s{0,},\s{0,}");
            /* Validate each file line. Log any line that fails
               any validation for any record column data into a
               List Interface object named: validationFailures
             */
            // Are there 4 Columns of data in each line...
            if (lineParts.length < 4) {
                sb.append("\t- Invalid Column Count!").append(ls);
                // Which column is missing...
                // *** You may need to add more conditions to suit your needs. ***
                if (checkAccountIDs(lineParts[0]) && lineParts.length >= 2 && !checkAccountIDs(lineParts[1])) {
                    sb.append("\t- Either the 'Sender Account ID' or the "
                            + "'ReceiverAccountID' is missing!").append(ls);
                }
                else if (lineParts.length >= 3 && !checkAmount(lineParts[2])) {
                    sb.append("\t- The 'Amount' value is missing!").append(ls);
                }
                else if (lineParts.length < 4) {
                    sb.append("\t- The 'Transfer Date' is missing!").append(ls);
                }
            }
            else {
                // Is SenderAccountID data valid...
                if (!checkAccountIDs(lineParts[0])) {
                    sb.append("\t- Invalid Sender Account ID in column 1! (")
                            .append(lineParts[0].equals("") ? "Null" : 
                                    lineParts[0]).append(")");
                    if (lineParts[0].length() < 9) {
                        sb.append(" <-- Not Enough Or No Digits!").append(ls);
                    }
                    else if (lineParts[0].length() > 9) {
                        sb.append(" <-- Too Many Digits!").append(ls);
                    }
                    else {
                        sb.append(" <-- Not All Digits!").append(ls);
                    }
                }
                // Is ReceiverAccountID data valid...
                if (!checkAccountIDs(lineParts[1])) {
                    sb.append("\t- Invalid Receiver Account ID in coloun 2! (")
                            .append(lineParts[1].equals("") ? "Null" : 
                                    lineParts[1]).append(")");
                    if (lineParts[1].length() < 9) {
                        sb.append(" <-- Not Enough Or No Digits!").append(ls);
                    }
                    else if (lineParts[1].length() > 9) {
                        sb.append(" <-- Too Many Digits!").append(ls);
                    }
                    else {
                        sb.append(" <-- Not All Digits!").append(ls);
                    }
                }
                // Is Amount data valid...
                if (!checkAmount(lineParts[2])) {
                    sb.append("\t- Invalid Amount Value in column 3! (")
                            .append(lineParts[2].equals("") ? "Null" : 
                                    lineParts[2]).append(")").append(ls);
                }
                // Is TransferDate data valid...
                if (!checkTransferDate(lineParts[3], "yyyy-MM-dd HH:mm:ss")) {
                    sb.append("\t- Invalid Transfer Date Timestamp in column 4! (")
                            .append(lineParts[3].equals("") ? "Null" : 
                                    lineParts[3]).append(")").append(ls);
                }
            }
            if (!sb.toString().equals("")) {
                validationFailures.add(sb.toString());
            }
        }
    }
    catch (FileNotFoundException ex) {
        System.err.println(ex.getMessage());
    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }

    // Display the Log...
    String timeStamp = new SimpleDateFormat("yyyy/MM/dd - hh:mm:ssa").
            format(new Timestamp(System.currentTimeMillis()));
    String dispTitle = "File Data Status at " + timeStamp.toLowerCase() 
                     + " <:-:> (" + filePath + "):";
    System.out.println(dispTitle + ls + String.join("", 
            Collections.nCopies(dispTitle.length(), "=")) + ls);
    if (validationFailures.size() > 0) {
        for (String str : validationFailures) {
            if (str.split(ls).length > 1) {
                System.out.println(str);
                System.out.println(String.join("", Collections.nCopies(80, "-")) + ls);
            }
        }
    }
    else {
        System.out.println("No Issues Detected!" + ls); 
    } 
}

private boolean checkAccountIDs(String accountID) {
    return (accountID.matches("\d+") && accountID.length() == 9);
}

private boolean checkAmount(String amount) {
    return amount.matches("-?\d+(\.\d+)?");
}

private boolean checkTransferDate(String transferDate, String format) {
    return isValidDateString(transferDate, format);
}

private boolean isValidDateString(String dateToValidate, String dateFromat) {
    if (dateToValidate == null || dateToValidate.equals("")) {
        return false;
    }
    SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
    sdf.setLenient(false);
    try {
        // If not valid, it will throw a ParseException
        Date date = sdf.parse(dateToValidate);
        return true;
    }
    catch (ParseException e) {
        return false;
    }
}

我不确定您的特定应用程序流程最终会带来什么,但如果其他流程正在访问该文件并对其进行修改,那么 可能 明智地利用 locking 机制在您的特定过程中 Lock 文件并在完成时 Unlock 文件。然而,这很可能需要您使用不同的读取算法,因为锁定文件必须通过 writable 通道完成。使用 java.nio 包中的 FileChannel and FileLock 类 可能会在这里为您提供帮助。在 Whosebug 论坛中会有如何使用这些 类 的示例。