老师上课演示了一个小的输入输出流的例子,发现了一个容易出错的点,老师说可以拿来出题,记录一下以免忘记。
功能:随机生成100个整数并写入文件,然后再通过流读取文件内容并在控制台输出内容。
错误代码:
public class MyFile {
public static void main(String... args) {
File file = new File("myFile.txt");
List<Integer> list = new ArrayList<>();
try(FileWriter writer = new FileWriter(file);
FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader)) {
Random random = new Random();
random.ints(100,1,100).forEach(n->{
String str = String.valueOf(n) + "\n";
try {
writer.write(str);
} catch (IOException e) {
e.printStackTrace();
}
});
reader.lines().forEach(line->{
list.add(Integer.valueOf(line));
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(list);
list.forEach(System.out::println);
}
上面的代码运行后结果是:文件可以正确生成,但是无法对文件进行读取,控制台没有任何内容,也没有报错。
最终找到错误,发现是因为FileWriter的流在未关闭的情况下是无法对FileReader流操作的,解决方法就是手动关闭FileWriter,或者将功能分离。
正确代码
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class MyFile {
public static void main(String... args) {
File file = new File("myFile.txt");
List<Integer> list = new ArrayList<>();
if(!file.exists())
CreateFile(file);
try(FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader)) {
reader.lines().forEach(line->{
list.add(Integer.valueOf(line));
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(list);
list.forEach(System.out::println);
}
public static void CreateFile(File file) {
try(FileWriter writer = new FileWriter(file)) {
Random random = new Random();
random.ints(100,1,100).forEach(e->{
String str = String.valueOf(e) + "\n";
try {
writer.write(str);
} catch (IOException ex) {
ex.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
Tip1:为了对文件进行逐行的读取,所以在fileReader的基础上再生成一个BufferedReader。
Tip2:这里应用到了try-with-resource,只要将资源放在try()的括号里面,在try-catch执行完之后,资源将自动关闭,无须手动操作。
Tip3:只要实现了Closable或者是AutoClosable的类都是属于资源,可以使用try-with-resource。