Java实现:先统计collect文件夹文件数再每分钟发送不同文件
Hey there! Let's work through your requirement step by step. You want to count all the selectDataXX.json files in your collect folder, then send a unique file every minute. Let's expand your existing code to make this happen.
Step 1: Fix the Folder Path Resolution
First, let's correctly get the path to your collect folder. Your current code starts getting the code source location, but we need to adjust it to point to the collect directory. Depending on whether collect is in your application's runtime directory or bundled as a resource, here's how to handle it:
public String getCollectFolderPath() { // Get the base path of your application String codeLocation = new SendSituationData().getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); File codeFile = new File(codeLocation); String basePath; // If running from a JAR, the code location is the JAR file itself if (codeFile.isFile()) { basePath = codeFile.getParent(); } else { // If running from IDE, it's the classes directory basePath = codeFile.getAbsolutePath(); } // Path to the collect folder (adjust if your folder is in a different location) String collectFolderPath = basePath + File.separator + "collect"; log.info("Collect folder path: {}", collectFolderPath); return collectFolderPath; }
Step 2: Count Total JSON Files in the Folder
Next, let's count all the valid JSON files in collect:
public int countJsonFiles(String collectFolderPath) { File collectFolder = new File(collectFolderPath); if (!collectFolder.exists() || !collectFolder.isDirectory()) { log.error("Collect folder does not exist or is not a directory: {}", collectFolderPath); return 0; } // Filter files that match selectDataXX.json pattern File[] jsonFiles = collectFolder.listFiles((dir, name) -> name.matches("selectData\\d{2}\\.json")); if (jsonFiles == null) { log.warn("No files found in collect folder"); return 0; } int totalFiles = jsonFiles.length; log.info("Total JSON files in collect folder: {}", totalFiles); return totalFiles; }
Step 3: Send Files Every Minute (Unique Each Time)
To send a unique file every minute, we'll use ScheduledExecutorService to handle the timing, and keep track of which files we've already sent. Here's how to integrate this:
private List<File> jsonFiles; private int currentIndex = 0; private ScheduledExecutorService scheduler; public void initFileSender() { String collectPath = getCollectFolderPath(); File collectFolder = new File(collectPath); // Get the list of JSON files (using the same filter as before) jsonFiles = Arrays.asList(collectFolder.listFiles((dir, name) -> name.matches("selectData\\d{2}\\.json"))); if (jsonFiles.isEmpty()) { log.error("No JSON files found to send"); return; } // Initialize the scheduler scheduler = Executors.newSingleThreadScheduledExecutor(); // Schedule the task to run every minute, starting immediately scheduler.scheduleAtFixedRate(this::sendNextFile, 0, 1, TimeUnit.MINUTES); } private void sendNextFile() { if (currentIndex >= jsonFiles.size()) { log.info("All files have been sent. Stopping scheduler."); scheduler.shutdown(); return; } File fileToSend = jsonFiles.get(currentIndex); log.info("Sending file: {}", fileToSend.getName()); // Add your file sending logic here (call your getData method or process the file) try { String fileContent = new String(Files.readAllBytes(fileToSend.toPath())); // Replace with your actual sending logic (e.g., send via HTTP, queue, etc.) log.info("File content preview: {}", fileContent.substring(0, 100) + "..."); } catch (IOException e) { log.error("Failed to read or send file: {}", fileToSend.getName(), e); } currentIndex++; }
Step 4: Integrate with Your Existing getData Method
If your getData method is meant to return the content of the current file to send, you can adjust it to use the file list we built:
public String getData() { if (jsonFiles == null || currentIndex >= jsonFiles.size()) { return "No more files to send"; } File currentFile = jsonFiles.get(currentIndex); try { return new String(Files.readAllBytes(currentFile.toPath())); } catch (IOException e) { log.error("Failed to read file: {}", currentFile.getName(), e); return "Error reading file"; } }
Important Notes
- Path Adjustment: If your
collectfolder is inside your project's resources directory (instead of the runtime directory), you'll need to usegetResourceorgetResourceAsStreamto access it (since it'll be inside the JAR). Let me know if you need help with that! - Error Handling: We added basic error handling, but you might want to expand it based on your use case (e.g., retry failed sends, handle empty folders gracefully).
- Thread Safety: If multiple threads are accessing the file sender, you'll need to add synchronization to the
currentIndexvariable.
内容的提问来源于stack exchange,提问作者Abbott Liu

