在方法getFileName()中创建了对象BufferedReader并将对象的引用分配给变量 - reader。然后在最后一个流关闭。
然后调用readStringsFromConsole()方法。创建相同的对象。但抛出IOException。为什么会这样?
ps:对不起我的英语:)
堆栈跟踪:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.test.home04.Solution.readStringsFromConsole(Solution.java:55)
代码:
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line))
break;
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}
答案 0 :(得分:4)
如果您从System.in
创建了一个阅读器并将其关闭,它也会关闭System.in
,即使您创建了另一个阅读器,也无法再次打开它。
简而言之 - 不要关闭从System.in
创建的读者。
正如安德烈亚斯在评论中指出的那样,一般准则应该是System.in
只能在命令行程序的生命周期内被包装一次(无论是Scanner
,{{1 ,或其他东西),它永远不应该被关闭。包装应该可能发生在BufferedReader
的开头,包装器对象应该传递或存储在字段(静态或实例)中。
答案 1 :(得分:1)
为什么会这样?
之所以发生这种情况,是因为您在getFilename
方法中关闭了System.in。
为什么不在关闭后打开流?
基本上,因为你不能,或者如果你问的是JVM的行为......&gt;&gt;它&lt;&lt;可&#39;吨
当调用close()
时,close将被发送到关闭并释放基础文件描述符的操作系统。关闭后,操作系统没有足够的信息来重新打开以前的文件。如果文件描述符用于(未命名的)管道或套接字流,则无法重新建立连接,因为:
另一端的应用程序或服务通常会消失,
对于TCP / IP套接字,协议不允许重新连接。
简而言之:如果您需要稍后从中读取或写入更多内容,请不要关闭流,并避免完全关闭System.{in,out,err}
。
现在,如果您的应用程序具有文件名或主机/端口,则可以打开新的FileReader
或连接新的套接字。但是对于System.*
流,该信息不可用于应用程序(或JVM)。
但在您的特定情况下,我怀疑您的意图是getFileName
一次返回一个提供的文件名;即每次调用都会返回 next 文件名。如果是这种情况,您将不得不以不同的方式实施它:
它不应该关闭流或阅读器。
它不应该打开读者(可能)。
它应该返回它读取的第一行(或下一行)而不是读取所有行并返回最后一行,就像它当前那样。
答案 2 :(得分:0)
您正在从System.in关闭流。在重新使用之前需要打开封闭的流。如果您从System.in创建它们,请不要关闭它们。 试试这个,
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line)) {
break;
}
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
System.out.println("Enter a file name: ");
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}