获取字符集时出现Stream closed error错误,求Java代码排查方案
解决「Stream closed error when getting charset」问题
嘿,我来帮你排查这个问题!你的代码里有两个关键问题导致了这个错误,咱们一个个拆解:
1. 核心问题:输入流被提前耗尽/关闭
你在创建InputStreamReader时调用了SidFileUtils.charsetDetection(is)——这个字符集检测方法大概率会读取输入流的前若干字节来判断编码,甚至有些实现会直接关闭流。而你的InputStream is是在try-with-resources里共享的,当检测方法用完流之后,流的指针已经走到末尾,或者直接被关闭了,后面再用这个流创建BufferedReader自然就会抛出「Stream closed」错误。
2. 次要问题:拼写错误
你提到的Chasrset.forNa是明显的笔误,正确写法应该是Charset.forName,这个不修正的话代码连编译都通不过。
修复方案
根据SidFileUtils.charsetDetection的实现不同,有两种常用的修复方式:
方式一:用PushbackInputStream保留流的可读状态
如果你的字符集检测方法只是读取流的字节但不会关闭它,用PushbackInputStream可以把检测时读取的字节推回流中,让后续的读取操作能从头开始:
try (InputStream is = new FileInputStream(file); PushbackInputStream pushbackIs = new PushbackInputStream(is, 1024); // 缓存足够检测编码的字节数,可根据实际调整 BufferedReader br = new BufferedReader(new InputStreamReader(pushbackIs, Charset.forName(SidFileUtils.charsetDetection(pushbackIs))))) { br.readLine(); br.readLine(); String line; while ((line = br.readLine()) != null) { lines.add(line); } } catch (ExceptionTechnique | IOException e) { LOG.error("Erreur lors de la lecture du fichier " + file.getName(), e); }
方式二:先把流内容复制到字节数组(适合小文件)
如果SidFileUtils.charsetDetection会关闭传入的流,那最好先把整个文件内容读到字节数组里,再用ByteArrayInputStream分别供检测和读取使用:
try (InputStream is = new FileInputStream(file)) { // 读取整个文件到字节数组(大文件不推荐,会占用过多内存) byte[] fileBytes = is.readAllBytes(); try (ByteArrayInputStream detectionStream = new ByteArrayInputStream(fileBytes); ByteArrayInputStream readStream = new ByteArrayInputStream(fileBytes); BufferedReader br = new BufferedReader(new InputStreamReader(readStream, Charset.forName(SidFileUtils.charsetDetection(detectionStream))))) { br.readLine(); br.readLine(); String line; while ((line = br.readLine()) != null) { lines.add(line); } } } catch (ExceptionTechnique | IOException e) { LOG.error("Erreur lors de la lecture du fichier " + file.getName(), e); }
内容的提问来源于stack exchange,提问作者Yaoming
相关产品推荐
相关产品推荐

