为什么读取两次后无法保存文件的内容?

  • 本文关键字:保存文件 两次 读取 java
  • 更新时间 :
  • 英文 :


已经修复。感谢 Mas & ruhul 观察我的错误。

我试图读取一个文本文件两次,名为 stationary.txt。文件的内容有三列,例如金额,产品名称和总价。

我首先要做的是通过逐行阅读来平均每种产品的价格。然后我关闭了缓冲,然后再次打开它并阅读。第二个读数采用可变平均值,并逐行比较每种产品的价格。如果第 1 行超过平均值,则将其写入 dearer.txt,否则将其写入 cheap.txt

这是文具.txt

1 Highlighter 5.99
2 Pen 9.00
3 Eraser 5.00
4 DrawingPin 2.75
5 Highlighter 10.99
6 FountainPen 20.50
7 Pencil 14.50

以下是源代码

import java.util.*;
import java.io.*;
public class Ques {
public static void main(String[] args) throws FileNotFoundException {
double average = 0;
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
File outFilel = new File("dearer.txt");
FileOutputStream outFileStreaml = new FileOutputStream(outFilel);
PrintWriter outStream1 = new PrintWriter(outFileStreaml);
File outFile2 = new File("cheap.txt");
FileOutputStream outFileStream2 = new FileOutputStream(outFile2);
PrintWriter outStream2 = new PrintWriter(outFileStream2);
computeAverage(bufReader, outStream1, outStream2, average);
}
public static void computeAverage(BufferedReader bufReader, PrintWriter outStream1, PrintWriter outStream2, double average) {
String line = "";
double mark = 0;
double sum = 0;
int count = 0;
try {
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]);
sum += mark;
count++;
}
average = sum / count;
compareMark(outStream1, outStream2, average);   
} catch (NumberFormatException | IOException e) {
System.out.println(e);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch ( IOException e) {
e.printStackTrace();
}
} 
}
}
public static void compareMark(PrintWriter outStream1, PrintWriter outStream2, double average) throws FileNotFoundException {
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
String line = " ";
double sum = 0;
double mark = 0;
int count = 0;
try {
double ave = (double) Math.round(average * 100) / 100;
System.out.println("another " + ave);
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
System.out.println(line);
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]); 
if (mark > ave) {
System.out.println("Over");
outStream1.write(line);
} else {
System.out.println("Less");
outStream2.write(line);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
} 
}
}   
}

源代码运行良好,只是在执行两次读取后,我收到了两个文件的 0 字节(第一次,做平均值,最后做比较(。为什么?我在这里做错了什么?

感谢您的帮助。

您的代码不正确,无法编译。但主要缺陷如下:

  1. 你的 Double.parseDouble(data[2]( 不应该与你的第 4 行数据一起使用。最好使用 Double.parseDouble(data[data.length - 1](
  2. 删除 while-loop 前面的 readLine(( 调用。
  3. 编写包含行分隔符的行。
  4. 关闭外流

您提供的数据文件具有用空格分隔的列。由于第 2 列包含包含空格的数据,因此将数据 [2] 转换为双精度将触发异常。这将使程序关闭缓冲区并退出。

使用逗号分隔列数据。

使用更好的异常处理来轻松查找异常。

您所需要的只是关闭这些输出流。由于您使用的是bufferredWriter,并且在每次写入后不刷新它,因此您需要关闭这些输出流。这会将这些行或数据写回文件中。下面是如何执行此操作的示例: 示例 1:使用 flush((。

....
outStream1.write(line);
outStream1.flush();
} else {
System.out.println("Less");
outStream2.write(line);
outStream2.flush();
}

示例 2:最有效(无论哪种方式,您都需要像 bufReader.close((一样关闭这些缓冲区(

...
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
// add try catch. 
outStream2.close();
outStream1.close();
if (bufReader != null ... ) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
} 
}

根据要求,使用List

的示例首先一个类要保存静止数据,必须完成:

public class Stationary {
private final int id;    // or String if desired
private final String name;
private final double mark;  // BigDecimal would be better for money
public Stationary(int id, String name, double mark) {
// TODO error checking
this.id = id;
...
}
public int getId() {
return id;
}
... // TODO other getters
// TODO equals, hashCode, toString
}

并读取文件:

public List<Stationary> read(File file) {
List<Stationary> list= new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
// TODO parse line into id, name, mark
list.add(new Stationary(id, name, mark);
}
}
return list;
}

现在,可以根据需要使用列表,例如平均值:

List<Stationary> stationaries = read(STATIONARY_FILE);
...
for (Stationary stationary : stationaries) {
sum += stationary.getMark();
count += 1;
}
...

流不用于保持简单

最新更新