try-with-resources语句中FileWriter资源无法赋值的解决方法
解决try-with-resources下动态创建输出文件的问题
问题根源
try-with-resources声明的资源变量是隐式final的,无法在块内重新赋值;同时你手动关闭资源再重建的逻辑,和try-with-resources的自动资源管理机制冲突,导致编译报错。
解决思路
- 把读文件的资源(
FileInputStream、BufferedReader)放在外层try-with-resources中,统一管理读取操作的资源释放。 - 每个输出分区文件单独用一个try-with-resources块创建
FileWriter和BufferedWriter,让JVM自动处理资源的关闭,无需手动调用close()或flush()。 - 调整读取逻辑:累计行数,达到限制时切换到新的输出文件,用新的try-with-resources块管理新的写资源。
修正后的代码示例
try (InputStream fis = new FileInputStream(sArquivo); BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { String vLinha; long lLinhas = 0L; long lPart = 1L; String currentOutputFile = sNomeArquivoDestino; // 处理第一个分区文件 try (FileWriter fw = new FileWriter(currentOutputFile); BufferedWriter bw = new BufferedWriter(fw)) { while ((vLinha = br.readLine()) != null) { bw.write(vLinha + System.lineSeparator()); lLinhas++; // 达到行数限制,结束当前文件的写入 if (lLinhas % lLimiteLinhas == 0L && lLinhas > 0L) { break; } } } // 处理剩余的分区文件 while ((vLinha = br.readLine()) != null) { lPart++; currentOutputFile = sPathDestino + "\\" + sFileName.replace(".TXT", "") + "-Part-" + String.format("%05d", lPart) + ".TXT"; // 新文件用独立的try-with-resources管理写资源 try (FileWriter newFw = new FileWriter(currentOutputFile); BufferedWriter newBw = new BufferedWriter(newFw)) { long linesInCurrentFile = 0; // 写入当前分区的所有行 while (linesInCurrentFile < lLimiteLinhas && vLinha != null) { newBw.write(vLinha + System.lineSeparator()); linesInCurrentFile++; lLinhas++; vLinha = br.readLine(); } } } } catch (Exception ex) { throw ex; }
额外优化点
- 替换原代码中
br.ready()的判断逻辑,改用while ((vLinha = br.readLine()) != null),这是读取文件行的标准可靠写法,避免因ready()返回值不准确导致的读取不完整。 - 每个分区文件的写资源都由try-with-resources自动关闭,完全符合Sonar的规则要求,不会出现资源泄漏问题。
内容的提问来源于stack exchange,提问作者Daniel Teodoro
相关产品推荐
相关产品推荐

