Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java file project: validate a manifest before producing a summary

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A staged file import validates an input batch before publishing derived results, so malformed records cannot quietly become accepted business state.

Java 8+. The program uses only JDK classes and runs without a framework.

Keep the file format deliberately small

This project reads UTF-8 lines of depot code and positive parcel count separated by one comma. It is not a CSV parser: quoted commas, multiline fields and escaping are outside its format. That restriction is part of the contract, not an invitation to label split(",") a complete CSV implementation.

The parser checks both field count and count syntax, then aggregates counts in insertion order. Math.addExact detects overflow instead of wrapping a depot total. The method returns a result only after every non-empty record has passed. A caller cannot observe its temporary map while a later record is still being validated.

The program writes an independent temporary input file, imports it, prints the completed summary and removes the file in finally. The deterministic output avoids including the randomly generated file path. A production import should put temporary files in an explicitly owned directory and define cleanup after process failure too.

Bound the demonstration before calling it a service

Files.readAllLines retains the whole file. This project is intended for small bounded manifests. A larger input needs buffered streaming, a line-length limit and limits on record count and distinct depot codes. Streaming alone does not bound an aggregation map if every record introduces another key.

If the summary must become a persistent replacement file, write it to a staging file and publish it with a file-system policy that handles unsupported atomic moves and failures. Printing to standard output is not transactional publication. The current project validates and summarizes; it makes no guarantee about a remote database or a crash-safe multi-file update.

Working program

Java
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
public class ManifestImport {
    static Map<String, Integer> read(Path input) throws IOException {
        Map<String, Integer> totals = new LinkedHashMap<>();
        int lineNumber = 0;
        for (String line : Files.readAllLines(input, StandardCharsets.UTF_8)) {
            lineNumber++;
            String[] fields = line.split(",", -1);
            if (fields.length != 2 || fields[0].trim().isEmpty()) {
                throw new IllegalArgumentException("Malformed line " + lineNumber);
            }
            String depot = fields[0].trim();
            int count = Integer.parseInt(fields[1].trim());
            if (count <= 0) throw new IllegalArgumentException("Invalid count at line " + lineNumber);
            totals.merge(depot, count, Math::addExact);
        }
        return totals;
    }
    public static void main(String[] args) throws IOException {
        Path input = Files.createTempFile("aitrove-manifest-", ".txt");
        try {
            Files.write(input, Arrays.asList("DL-01,4", "PN-02,3", "DL-01,6"), StandardCharsets.UTF_8);
            System.out.println(read(input));
            Files.write(input, Arrays.asList("DL-01,4", "PN-02,-3"), StandardCharsets.UTF_8);
            try { read(input); }
            catch (IllegalArgumentException rejected) { System.out.println("Invalid batch rejected"); }
        } finally {
            Files.deleteIfExists(input);
        }
    }
}

Output

Output
{DL-01=10, PN-02=3}
Invalid batch rejected

Cost and failure boundaries

For B input text units and k distinct depot codes, parsing and expected hash-map aggregation take O(B) work, assuming ordinary hash distribution and bounded numeric fields. This readAllLines version retains O(B+k) storage; a streamed version can reduce input retention but still needs O(k) aggregation storage.

Test an empty file, a missing comma, an extra comma, an empty depot, an absent numeric field, overflow and a malformed record late in a batch. Verify that failed parsing produces no returned partial summary. Filesystem permission errors and malformed business records should remain distinguishable in the caller’s diagnostics.

Common Mistakes

  • Do not call a restricted comma-separated format a general CSV parser.
  • Do not retain an unbounded file or unbounded number of keys without admission limits.
  • Do not publish a partial summary before the batch has passed validation.

Connect the contracts

Separate input validation from the decision to publish a file.

Compare a single import with failure-preserving imports before introducing workers.

Compare the boundary explained in File ownership with the assumptions made by this program.

java
manifest-project
Storage details