如何从可能存在或不存在的文件中读取字符串?

时间:2014-10-20 20:39:49

标签: java string file while-loop printwriter

我正在编写一个程序,打开一个最初看起来像这样的文件:

3000.0
Lamps 15.3 400
Chairs 19.95 250
Desks 95.0 300

其中第一行是公司的余额,其余行分别包含产品名称,价格和数量。

但是,在整个程序中,我们对文件进行了更改,并使用Printwriting对象保存最后完成的操作。我们在程序过程中可以做的一件事是向库存添加新项目。但是,我必须能够阅读具有多个名称的产品,例如桌椅。正如我的代码现在编写的那样,文件只读取名称,然后直接移动到价格,所以如果我尝试读取多个单词的名称,它会给我一个运行时错误,因为我试图读取一个字符串有一个双。因此,我如何阅读可能或可能没有两个字符串的行?并且,如果有两个字符串,我如何编写它以便将它们存储在同一个String变量中?这是我的代码:

    File file = new File("inventory.txt");
    Scanner inputFile = new Scanner(file);

    ArrayList<String> productName = new ArrayList<String>();
    ArrayList<Double> productQuantity = new ArrayList<Double>();
    ArrayList<Double> productPrice = new ArrayList<Double>();

    double balance = inputFile.nextDouble();

    while (inputFile.hasNext())
    {
        String product = inputFile.next();
        double price = inputFile.nextDouble();
        double quantity = inputFile.nextDouble();

        //Takes those variables and stores each of them in ArrayList objects
        productName.add(product);
        productPrice.add(price);
        productQuantity.add(quantity);
    }

    inputFile.close();

4 个答案:

答案 0 :(得分:1)

您可以做的一件事是将空格用连字符或其他字符替换,同时将其存储在文件中。这样,您只需将其读出为单个单词,然后只需用空格替换该字符,从而避免更改您提供的代码。

但是如果您无法控制文件的编写方式,那么您可以尝试将nextDouble()函数放在try块中,以查看您是在查看价格还是名称的下一个单词。请注意,如果产品名称的第二个单词是数字,则不会按设计工作。

File file = new File("inventory.txt");
Scanner inputFile = new Scanner(file);

ArrayList<String> productName = new ArrayList<String>();
ArrayList<Double> productQuantity = new ArrayList<Double>();
ArrayList<Double> productPrice = new ArrayList<Double>();

double balance = inputFile.nextDouble();

while (inputFile.hasNext())
{
    String product = inputFile.next();
    try{ 
        double price = inputFile.nextDouble();
    }
    catch(Exception e){
        product = product+" "+inputFile.next();
        double price = inputFile.nextDouble();
    }
    double quantity = inputFile.nextDouble();

    //Takes those variables and stores each of them in ArrayList objects
    productName.add(product);
    productPrice.add(price);
    productQuantity.add(quantity);
}

inputFile.close();

答案 1 :(得分:1)

假设您不想更改输入文件格式,可以检查您正在阅读的字符串是否为数字。

public static boolean isNumeric(String str)  
{  
 try  
 {  
  double d = Double.parseDouble(str);  
 }  catch(NumberFormatException nfe)  
    {  
      return false;  
    }  
 return true;  
}

要将两个字符串存储在同一个变量中,请使用StringBuffer以防第二个String不是数字,并稍后将StringBuffer转换为String。

答案 2 :(得分:0)

好的,如果您想维护自己的格式,您需要重新构建代码,以便以更简单的方式表示数据。首先,您需要一个Object。我们称之为Product

public class Product {
    private String name;
    private int quantity;
    private double price;

    public Product(String name, int quantity, double price) {
        this.name = name;
        this.quantity = quantity;
        this.price = price;
    }
}

现在你已经为每个块提供了很好的表示,你需要一个很好的方法来编写它们。现在,您有效地将String写回File,所以让我们使用toString()方法来确定其外观:

public String toString() {
    return name + " " + quantity + " " + price;
}

然后,您在覆盖模式下打开FileWriter,循环浏览新的List Product类型,然后只需编写toString()价值。您会注意到我未在此处提供具体的代码示例。你可以解决它!

此方法的优点

  • 最重要的是您拥有整个文件的对象表示。这意味着在应用程序的生命周期内,您可以更新对象列表,而无需触摸文件。

<强>缺点

  • 每当您保存时,您都需要重写整个文件。如果您在保存数据时非常聪明,那么您就可以了。

答案 3 :(得分:0)

不要使用扫描仪,使用缓冲读卡器,逐行读取,然后拆分结果并根据计数进行解析:

File file = new File("inventory.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
double balance = Double.parseDouble(reader.readLine());
while (true) {
  String line = reader.readLine();
  if (line == null) {
    break;
  }
  String[] parts = line.split(" ");
  int count = parts.length;
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < count - 2; i++) {
    if (i > 0) {
      i.append(' ');
    }
    sb.append(parts[i]);
  }
  String productName = sb.toString();
  double price = Double.parseDouble(parts[count - 2]);
  double quantity = Double.parseDouble(parts[count - 1]);

  productName.add(product);
  productPrice.add(price);
  productQuantity.add(quantity);
}
reader.close();