Java中BufferedReader单独读取文件返回null问题求解
问题根因
- BufferedReader指针不会自动重置
你在类构造阶段就初始化了全局唯一的BufferedReader实例,它会持续记录当前读取的文件偏移量。首次调用read方法遍历完所有行后,指针会停在文件末尾(EOF),后续再调用read方法时,readLine()直接返回null,自然读不到内容。
在add方法内调用read能读到内容的原因是:写入新内容后文件长度增加,指针位置对应的偏移量不再是EOF,所以能读到刚写入的新内容。 - 字符串匹配逻辑错误
line.split(" ").equals(key)的写法完全错误:split()方法返回的是字符串数组,数组和字符串直接调用equals()永远返回false,永远匹配不到目标key。 - 同文件读写流不同步
全局共用同一个FileWriter和FileReader实例,两者的缓冲区相互独立,Reader无法实时感知Writer flush之后的内容更新,也会出现读取不到的情况。 - delete方法逻辑错误
原delete方法循环内两次调用readLine(),会跳过一半的行,无法正常匹配目标内容。
修复方案
1. 调整流的创建逻辑
放弃全局Reader/Writer实例,每次调用读写方法时独立创建流,操作完成后自动关闭,避免指针偏移和缓冲不同步问题。
2. 修正匹配规则
如果需要匹配行首第一个空格前的内容作为key,改为line.split(" ")[0].equals(key);如果需要匹配整行内容,直接用line.equals(key)即可。
3. 核心代码优化示例
public class FileManager { Path dataDir; File f; public static Logger logger = Logger.getLogger(FileManager.class.getName()); public FileManager(Path dataDir) throws IOException { logger.info("in file manager: "); this.dataDir = dataDir; String dirName = dataDir.toString(); String fileName = "fifo2.txt"; File dir = new File (dirName); dir.mkdirs(); f = new File (dir, fileName); logger.info("file established at "+f.getAbsolutePath()); if(!f.exists()){ logger.info("file not there so create new one "); f.createNewFile(); logger.info("file created!!! "); }else{ logger.info("file already exists"); System.out.println("File already exists"); } logger.info("file stage complete"); } public String add(String data) throws IOException{ // try-with-resources语法自动关闭流 try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(f, true))){ bufferedWriter.write(data); // 写入后追加换行,避免多段内容拼接为同一行 bufferedWriter.newLine(); logger.info("written " +data); } return data; } public String read(String key) throws IOException{ logger.info("start reading ...: "); try(BufferedReader bufferedReader = new BufferedReader(new FileReader(f))){ String line = bufferedReader.readLine(); while (line!= null) { logger.info("loop start reading ...: "+line); // 按需调整匹配规则,此处以匹配整行为例 if(line.equals(key)) { logger.info("reading line: "+line); return line; } line = bufferedReader.readLine(); } } return "F"; } public String delete(String key) throws IOException{ logger.info("Entering deletion in file storage"); List<String> allLines = new ArrayList<>(); // 先读所有内容到内存修改 try(BufferedReader bufferedReader = new BufferedReader(new FileReader(f))){ String line; while ((line = bufferedReader.readLine()) != null) { if(line.equals(key)) { allLines.add("DELETED"); logger.info("del_reading line: DELETED"); }else{ allLines.add(line); } } } // 修改后覆盖写入文件 try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(f))){ for (String line : allLines) { bufferedWriter.write(line); bufferedWriter.newLine(); } } return "F"; } }
内容的提问来源于stack exchange,提问作者Mohamed Yehia
相关产品推荐
相关产品推荐

