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

Java二进制文件读取优化问题:如何完整读取文件内容、避免额外空格并确保循环执行完毕

Hey there, let's work through the issues in your code and get it working properly. I see three main things to fix: the missing last card entry, ensuring clean file reading, and avoiding extra spaces in the formatted card number.

Why the last card isn't processed

Your current read logic has a classic "read-before-process" flaw:

  • You first read a long into data before entering the loop
  • Inside the loop, you convert the existing data to a string, then immediately read the next long
  • When you hit the end of the file, the readLong() call throws an exception before you can process the last data value you already read. That's why your final test case never gets handled.

Fixing the loop & file handling

We'll rearrange the flow to process each value right after reading it, and use try-with-resources to safely manage your input streams (so you don't have to manually close them, which avoids resource leaks). We'll also catch EOFException specifically (this is what readLong() throws when it hits the end of the file) instead of a broad IOException—this lets us cleanly exit the loop when there's no more data, while still catching other real errors like missing files.

Ensuring no extra spaces

Your existing spacing logic is almost there, but we can tweak it to be more robust (it works for 16-digit cards, but this adjustment handles all lengths) and guarantee no trailing space at the end of the card number.

Fixed Code

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;

public class CardNumber {
    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Enter a filename");
        String input = keyboard.nextLine();
        
        // Try-with-resources auto-closes streams when we're done
        try (FileInputStream basic = new FileInputStream(input);
             DataInputStream inputFile = new DataInputStream(basic)) {
            
            while (true) {
                long data;
                try {
                    data = inputFile.readLong(); // Read first, then process the value
                } catch (EOFException e) {
                    break; // Exit loop cleanly when end of file is reached
                }
                
                String cardNumber = String.valueOf(data);
                System.out.print("Credit card number: ");
                
                // Format with spaces every 4 digits, no trailing space
                for (int i = 0; i < cardNumber.length(); i++) {
                    System.out.print(cardNumber.charAt(i));
                    // Add space only if we're at a 4-digit boundary AND not the last character
                    if ((i + 1) % 4 == 0 && i != cardNumber.length() - 1) {
                        System.out.print(" ");
                    }
                }
                System.out.println();
                
                // Calculate Luhn checksum
                int sum = 0;
                int len = cardNumber.length();
                
                // Process every other digit starting from second last
                for (int i = len - 2; i >= 0; i -= 2) {
                    int digit = (cardNumber.charAt(i) - '0') * 2;
                    sum += digit % 10 + digit / 10; // Split two-digit values and add
                }
                
                // Process remaining digits
                for (int i = len - 1; i >= 0; i -= 2) {
                    sum += cardNumber.charAt(i) - '0';
                }
                
                System.out.println("Checksum: " + sum);
                System.out.print("Card status: ");
                System.out.println(sum % 10 == 0 ? "VALID" : "INVALID");
            }
            
        } catch (IOException e) {
            System.err.println("Error reading file: " + e.getMessage());
        } finally {
            keyboard.close();
        }
    }
}

Key Improvements:

  1. Read-then-process flow: We read a long, then immediately process it. When EOFException is thrown, we exit the loop—no unprocessed data left behind.
  2. Try-with-resources: Automatically closes your input streams, so you don't have to remember to call close() (which prevents resource leaks).
  3. Clean spacing: The adjusted condition ensures we never add a trailing space after the last digit, regardless of the card number length.
  4. Targeted exception handling: Catching EOFException separately lets us distinguish between "end of file" (expected) and other IO errors (like file not found, which we handle with an error message).

内容的提问来源于stack exchange,提问作者Trinidad James

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:22:46