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

Java代码输入文件名时始终抛出FileNotFoundException问题排查

分隔符匹配工具的FileNotFoundException排查

我编写了一段用于检查输入文件中分隔符匹配情况的Java代码,但无论输入哪个已存在的文件名(包括Eclipse项目中的文件以及numbersonnumbers.txt),都会触发FileNotFoundException异常,提示"File not found. Please try again.",找不到问题出在哪里。相关代码如下:

import java.io.*;
import java.util.Stack;

class DelimiterChecker {
    private BufferedReader reader;
    private int lineNumber = 1;
    private int charNumber = 0;

    public DelimiterChecker(String fileName) throws FileNotFoundException {
        reader = new BufferedReader(new FileReader(fileName));
    }

    public Character getNextCharacter() throws IOException {
        int charCode;
        char character;

        while ((charCode = reader.read()) != -1) {
            charNumber++;
            character = (char) charCode;

            // 检查注释、字面量并跳过
            if (character == '/') {
                if (reader.markSupported()) {
                    reader.mark(1);
                    char nextChar = (char) reader.read();
                    if (nextChar == '/') {
                        // 单行注释,跳转到行尾
                        while (character != '\n' && charCode != -1) {
                            charCode = reader.read();
                            character = (char) charCode;
                            charNumber++;
                        }
                        lineNumber++;
                        charNumber = 0;
                    } else if (nextChar == '*') {
                        // 多行注释,跳转到"*/"
                        boolean commentEnd = false;
                        while (!commentEnd && charCode != -1) {
                            charCode = reader.read();
                            character = (char) charCode;
                            charNumber++;
                            if (character == '*') {
                                reader.mark(1);
                                char next = (char) reader.read();
                                if (next == '/') {
                                    commentEnd = true;
                                }
                            } else if (character == '\n') {
                                lineNumber++;
                                charNumber = 0;
                            }
                        }
                    } else {
                        reader.reset();
                        return character;
                    }
                } else {
                    return character;
                }
            } else if (character == '"') {
                // 字符串字面量,跳转到闭合双引号
                while ((character != '"' || (character == '"' && charCode > 0 && (char) reader.read() == '\\')) && charCode != -1) {
                    charCode = reader.read();
                    character = (char) charCode;
                    charNumber++;
                }
            } else if (character == '\'') {
                // 字符字面量,跳转到闭合单引号
                while ((character != '\'' || (character == '\'' && charCode > 0 && (char) reader.read() == '\\')) && charCode != -1) {
                    charCode = reader.read();
                    character = (char) charCode;
                    charNumber++;
                }
            } else if (character == '\n') {
                lineNumber++;
                charNumber = 0;
            } else {
                return character;
            }
        }
        return null; // 文件结束
    }

    public String getCurrentPosition() {
        return "Line " + lineNumber + ", Char " + charNumber;
    }
}

public class DelimiterMatching {
    public static void main(String[] args) {
        BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
        String fileName;
        DelimiterChecker delimiterChecker;

        while (true) {
            try {
                System.out.print("Enter the filename: ");
                fileName = keyboard.readLine();
                delimiterChecker = new DelimiterChecker(fileName);
                break;
            } catch (FileNotFoundException e) {
                System.out.println("File not found. Please try again.");
            } catch (IOException e) {
                System.out.println("Error reading input. Please try again.");
            }
        }

        Stack<Character> delimiterStack = new Stack<>();
        Character currentChar;
        int position = 1;

        try {
            while ((currentChar = delimiterChecker.getNextCharacter()) != null) {
                if ("([{".contains(currentChar.toString())) {
                    delimiterStack.push(currentChar);
                } else if (")]}".contains(currentChar.toString())) {
                    if (delimiterStack.isEmpty()) {
                        System.out.println("Mismatched right delimiter '" + currentChar + "' at " + delimiterChecker.getCurrentPosition());
                        return;
                    }
                    char leftDelimiter = delimiterStack.pop();
                    if ((currentChar == ')' && leftDelimiter != '(') || (currentChar == ']' && leftDelimiter != '[') || (currentChar == '}' && leftDelimiter != '{')) {
                        System.out.println("Mismatched delimiters: '" + leftDelimiter + "' and '" + currentChar + "' at " + delimiterChecker.getCurrentPosition());
                        return;
                    }
                }
                position++;
            }

            if (!delimiterStack.isEmpty()) {
                char leftDelimiter = delimiterStack.pop();
                System.out.println("Mismatched left delimiter '" + leftDelimiter + "' at the end of the file.");
            } else {
                System.out.println("Delimiters are properly matched.");
            }
        } catch (IOException e) {
            System.out.println("Error reading input.");
        }
    }
}

可能的原因及解决方法

  • 相对路径定位错误:程序的工作目录可能和你预期的不一致。比如在Eclipse中,默认工作目录是项目根目录,而非src文件夹。如果文件放在src下,需要输入src/文件名.txt;或者直接使用文件的绝对路径(比如C:/project/numbersonnumbers.txt)来测试。
  • 文件名输入错误:注意文件名的大小写(Linux/macOS系统大小写敏感)、空格或特殊字符,输入时避免拼写错误。
  • 添加路径调试代码:修改DelimiterChecker的构造函数,先打印文件的绝对路径,确认程序实际查找的位置是否正确:
    public DelimiterChecker(String fileName) throws FileNotFoundException {
        File file = new File(fileName);
        // 打印实际路径,方便排查
        System.out.println("程序查找的文件路径:" + file.getAbsolutePath());
        if (!file.exists()) {
            throw new FileNotFoundException("文件不存在:" + file.getAbsolutePath());
        }
        reader = new BufferedReader(new FileReader(file));
    }
    
    这样能直观看到程序找的是哪个文件,快速定位路径问题。
  • 后续优化建议:使用try-with-resources自动关闭流,避免资源泄漏:
    // 在main方法中创建DelimiterChecker时改用try-with-resources
    try (DelimiterChecker delimiterChecker = new DelimiterChecker(fileName)) {
        // 原有处理逻辑
    } catch (IOException e) {
        // 异常处理
    }
    
    同时DelimiterChecker需要实现AutoCloseable接口,重写close()方法关闭reader。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:27:05