【问题标题】:Writing to a instance variables to a text file将实例变量写入文本文件
【发布时间】:2013-12-06 15:51:03
【问题描述】:

我需要获取对象列表并将它们的实例变量写入文本文件。它看起来像这样:

Hot Dog,1.25,Grocery Store
Gas,42.15,Gas Station
etc.

我有一些看起来像这样的代码:

public void writeListToFile(String fileName, ArrayList<BudgetItem> writeList) throws Exception {
    PrintWriter out = null;
    for(int i = 0; i<writeList.size(); i++) {   
        if(writeList.get(i) instanceof Expense) {
            Expense writeExpense = (Expense) writeList.get(i);
            try {
                out = new PrintWriter(new FileWriter(fileName));
                dump(out, writeExpense);
            }
            finally {
            }
        }
        else if(writeList.get(i) instanceof Income) {
            Income writeIncome = (Income) writeList.get(i);
            try {
                out = new PrintWriter(new FileWriter(fileName));
                dump(out, writeIncome);
            }
            finally {
            }
        }
    }
    out.close();
}

public void dump(PrintWriter out, Expense writeExpense) {
    out.print(writeExpense.getDateOfTransaction().get(GregorianCalendar.YEAR));
    out.print(",");
    out.print(writeExpense.getDateOfTransaction().get(GregorianCalendar.MONTH));
    out.print(",");
    out.print(writeExpense.getDateOfTransaction().get(GregorianCalendar.DATE));
    out.print(",");
    out.print(writeExpense.getItemName());
    out.print(",");
    out.print(writeExpense.getMethodOfPay());
    out.print(",");
    out.print(writeExpense.getPlaceOfPurchase());
    out.print(",");
    out.print(writeExpense.getQuantity());
    out.print(",");
    out.print(writeExpense.getPrice());
    out.print("\n");
}

and one other method similar to the 2nd one.

当我运行它时,它只写出一行,即列表中的第一个对象,没有其他内容。我不知道发生了什么事。我知道对象序列化是一个更快的选择,但是对于这个项目,由于我还在学习,我想使用这种方式。

答案之一要求的主要方法:

public static void main(String[] args) throws Exception {
    String itemName = "Hot Dog";
    int quantity = 1;
    String placeOfPurchase = "Weiner Stand";
    String methodOfPay = "Credit";
    BigDecimal price = new BigDecimal(1.25);
    GregorianCalendar g = new GregorianCalendar(2013,11,1);
    Expense e = new Expense(g, price, itemName, quantity, placeOfPurchase, methodOfPay);
    BudgetItem bi = (BudgetItem) e;
    String itemName2 = "Gun";
    int quantity2 = 1;
    String placeOfPurchase2 = "Weiner Stand";
    String methodOfPay2 = "Credit";
    BigDecimal price2 = new BigDecimal(1.25);
    GregorianCalendar g2 = new GregorianCalendar(2013,11,1);
    Expense e2 = new Expense(g, price, itemName, quantity, placeOfPurchase, methodOfPay);
    BudgetItem bi2 = (BudgetItem) e2;
    ArrayList<BudgetItem> abi = new ArrayList<BudgetItem>();
    abi.add(bi);
    abi.add(bi2);
    RegisterFileIO rfio = new RegisterFileIO();
    rfio.writeListToFile(System.getProperty("user.dir") + "/data.out", abi);


    BufferedReader in = new BufferedReader(new FileReader(System.getProperty("user.dir") + "/data.out"));
    Scanner lineScanner = new Scanner(in);
    lineScanner.useDelimiter(",");
    while(lineScanner.hasNext()) {
        System.out.println(lineScanner.next());
    }
}

【问题讨论】:

  • 未测试,但我认为问题在于您为列表中的每个项目创建了一个新的PrintWriter。尝试在for 循环之外创建PrintWriter
  • 为什么不把创建输出的责任放在每种类型的toString() 方法上呢?那么你只需要为每个对象做一次System.out.println(writeExpense);
  • 打印出哪一行?循环中的第一个还是循环中预期的最后一个?
  • 它只打印循环中的第一个。
  • 你确定吗?试试System.out.println(writeList.get(writeList.size() - 1);。看看它打印出来的东西。我有一种感觉,它打印出最后一个而不是第一个。我可能是错的,但如果我是对的,我想我知道问题所在。

标签: java filewriter printwriter


【解决方案1】:

我相信问题在于您每次迭代都会创建一个新的PrintWriter。您应该在循环之外声明它。发生的情况是,当创建新的PrintWriter 时,它会覆盖文件中存储的先前数据。

PrintWriter out = null;
try {
    out = new PrintWriter(new FileWriter(fileName));
    for(int i = 0; i<writeList.size(); i++) {   
        if(writeList.get(i) instanceof Expense) {
            Expense writeExpense = (Expense) writeList.get(i);

            dump(out, writeExpense);
    }
 } finally {
 }

【讨论】:

  • 好的,这在一定程度上解决了这个问题。它现在每次都写入同一个对象,并且即使我在转储方法的末尾打印一个换行符,它也不会在新行上写入每个新对象。也许还有回车?
  • 1) 你需要使用println(),而不是print("\n"); 2) 你的数组中的对象很可能引用了同一个对象。您想在填充列表的位置显示代码吗?
  • 你使用了两次 e BudgetItem bi = (BudgetItem) e;
  • 对所有 BudgetItems 执行此操作。您正在做的是引用相同的 BudgetItem e
  • 哈哈,谢谢,否则我不会注意到。我对此感到很愚蠢。
【解决方案2】:

这是因为您正在为列表中的每个对象实例化一个新的 PrintWriter 对象(和一个新的 FileWriter 对象)。

您应该只在 for 循环之前实例化一次。替换

PrintWriter out = null;

PrintWriter out = new PrintWriter(new FileWriter(fileName));

附带说明:使用您当前的代码,如果您的 ArrayList 为空,您可能会在 out.close(); 行得到一个 NullPointerException

【讨论】:

    【解决方案3】:

    首先:您正在编写 java,而不是 C++。使用 Java 结构和技术。

    正如 MadConan 所说,您的实现过于矫枉过正。在每个对象类型(支出和收入)上使用 toString()(或 toBlammy() - blammy 不是字符串)来格式化输出。

    提示:只要你有一堆if (instanceof blammy),你就应该考虑多态性。

    您的代码应如下所示:

    public void writeListToFile(
        final String fileName,
        final List<BudgetItem> listBudgetItem)
    throws Exception
    {
        PrintWriter out = null;
    
        try
        {
            out = new PrintWriter(new FileWriter(fileName));
            for(BudgetItem current : listBudgetItem)
            {
                out.println(current.toBlammy());
            }
        }
        catch (... exceptions)
        {
        }
        finally
        {
            // close the PrintWriter.
        }
    }
    

    【讨论】:

    • 感谢您的帮助,我很感激您花时间看我的东西,但我要说的是,我是一名正在努力学习的学生。当我完成这个项目时,我正在学习各种各样的东西,包括多态性、序列化等。即使我已经学会了这些,我也有一个截止日期要赶上,几乎没有时间回去改变我的整体程序。我不明白你提出建议的背景。
    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 2019-05-12
    相关资源
    最近更新 更多