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

如何优化Java文件验证代码的循环?遇错误状态需终止执行

优化方案说明

原代码的嵌套while循环存在阻塞逻辑混乱、全表查询效率低、未处理错误状态的问题,以下是针对性优化后的实现:

核心优化点

  • 将嵌套循环改为定时轮询+超时控制的逻辑,避免WatchService阻塞导致无法正常检测数据库状态
  • 数据库查询改为按文件名精准查询,减少IO开销
  • 新增错误状态检测逻辑,遇到错误直接终止流程并打印详情
  • 提取独立方法封装状态检测逻辑,提升代码可读性

修改后的Application类代码

package com.file.verifier;

import java.io.IOException;
import java.nio.file.*;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Application {

    private static final String FOLDER_PATH = "D:\\EntityImportEversana";
    // 可配置的轮询参数
    private static final long POLL_INTERVAL_SECONDS = 1;
    private static final long MAX_WAIT_MINUTES = 30;

    public static void main(final String[] args) throws IOException, InterruptedException {
        System.out.println("Running file verifier");
        System.out.println("Monitoring folder: " + FOLDER_PATH);
        SqlUtils sqlUtils = new SqlUtils();

        try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
            Path path = Paths.get(FOLDER_PATH);
            // 只监听文件删除事件,缩小监听范围
            path.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);

            WatchKey key;
            while ((key = watchService.take()) != null) {
                for (WatchEvent<?> event : key.pollEvents()) {
                    if (StandardWatchEventKinds.ENTRY_DELETE.equals(event.kind())) {
                        String fileName = event.context().toString();
                        System.out.printf("Detected deletion of file: %s%n", fileName);
                        monitorFileImportStatus(sqlUtils, fileName);
                    }
                }
                key.reset();
            }
        }
    }

    private static void monitorFileImportStatus(SqlUtils sqlUtils, String fileName) throws InterruptedException {
        Instant startTime = Instant.now();
        boolean monitoring = true;

        while (monitoring) {
            // 查询当前文件的导入状态
            List<String> statusInfo = sqlUtils.getFileImportStatus(fileName);
            if (statusInfo == null) {
                System.out.printf("Warning: No record found for file %s, retrying...%n", fileName);
            } else {
                String status = statusInfo.get(0);
                switch (status) {
                    case "Completed":
                        System.out.printf("File %s imported successfully%n", fileName);
                        monitoring = false;
                        break;
                    case "Error":
                        System.err.printf("Error processing file %s! Details: %s%n", fileName, statusInfo.get(1));
                        // 终止整个程序
                        System.exit(1);
                    default:
                        System.out.printf("File %s is still processing, current status: %s%n", fileName, status);
                }
            }

            // 检查是否超时
            if (Duration.between(startTime, Instant.now()).toMinutes() >= MAX_WAIT_MINUTES) {
                System.err.printf("Timeout waiting for file %s to complete processing%n", fileName);
                System.exit(1);
            }

            TimeUnit.SECONDS.sleep(POLL_INTERVAL_SECONDS);
        }

        // 打印耗时
        Duration duration = Duration.between(startTime, Instant.now());
        System.out.printf("Processing time: %d minutes %d seconds%n",
                duration.toMinutes(), duration.getSeconds() % 60);
    }
}

修改后的SqlUtils类代码

package com.file.verifier;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class SqlUtils {

    private static final String CONNECTION_URL = "jdbc:sqlserver://......";

    // 按文件名精准查询状态,避免全表扫描
    public List<String> getFileImportStatus(String fileName) {
        String query = "SELECT Status, ErrorMessage, OtherDetails FROM integration.EntityImportRequests WHERE FileName = ?";
        try (Connection connection = DriverManager.getConnection(CONNECTION_URL);
             PreparedStatement stmt = connection.prepareStatement(query)) {

            stmt.setString(1, fileName);
            try (ResultSet resultSet = stmt.executeQuery()) {
                if (resultSet.next()) {
                    List<String> statusInfo = new ArrayList<>(3);
                    statusInfo.add(resultSet.getString("Status"));
                    statusInfo.add(resultSet.getString("ErrorMessage"));
                    statusInfo.add(resultSet.getString("OtherDetails"));
                    return statusInfo;
                }
            }
        } catch (SQLException e) {
            System.err.println("Database query failed:");
            e.printStackTrace();
            // 数据库异常直接终止
            System.exit(1);
        }
        return null;
    }
}

关键优化细节

  1. 轮询逻辑重构:

    • 移除嵌套的WatchService循环,改用定时休眠+主动查询数据库的方式,避免WatchService阻塞导致状态检测停滞
    • 添加最大等待超时时间,防止无限轮询
  2. 数据库查询优化:

    • 使用PreparedStatement按文件名精准查询,避免全表扫描,提升查询效率
    • 只查询需要的字段(状态、错误信息等),减少数据传输
  3. 错误处理增强:

    • 检测到"Error"状态时,打印错误详情并直接终止程序
    • 数据库查询异常时,打印堆栈信息并终止
    • 添加超时终止逻辑,避免无限等待
  4. 代码可读性提升:

    • 将状态检测逻辑提取到独立方法monitorFileImportStatus中
    • 使用常量定义配置参数,便于后续修改
    • 格式化输出日志,更清晰直观

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:12:26