【问题标题】:Writing an object array to csv file in java在java中将对象数组写入csv文件
【发布时间】:2019-03-01 16:18:05
【问题描述】:

我正在尝试获取一个初始 CSV 文件,将其传递给一个类,该类检查另一个文件是否具有 A 或 D,然后添加或删除数组对象的关联条目。

pokemon.csv 示例:

1, Bulbasaur
2, Ivysaur
3, venasaur

changeList.csv 示例:

A, Charizard
A, Suirtle
D, 2

话虽如此,我在将新数组的内容转换为新的 CSV 文件时遇到了很多麻烦。我检查了我的数组和类文件是否正常工作。我一直在尝试将“pokedex1”对象数组的最终内容放入新的 CSV 文件中,但未能成功。

主文件

import java.io.File; 
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class PokedexManager {

public static void  printArray(String[] array) {
    System.out.print("Contents of array: ");

    for(int i = 0; i < array.length; i++) {
        if(i == array.length - 1) {
            System.out.print(array[i]);
        }else {
            System.out.print(array[i] + ",");
        }
    }
    System.out.println();
}

public static void main(String[] args) {
    try {
        //output for pokedex1 using PokemonNoGaps class
        PokemonNoGaps pokedex1 = new PokemonNoGaps();

        //initializes scanner to read from csv file
        String pokedexFilename = "pokedex.csv";
        File pokedexFile = new File(pokedexFilename);
        Scanner pokescanner = new Scanner(pokedexFile);

        //reads csv file, parses it into an array, and then adds         new pokemon objects to Pokemon class
        while(pokescanner.hasNextLine()) {
            String pokeLine = pokescanner.nextLine();
            String[] pokemonStringArray = pokeLine.split(", ");
            int id = Integer.parseInt(pokemonStringArray[0]);
            String name = pokemonStringArray[1];
            Pokemon apokemon = new Pokemon(id, name);
            pokedex1.add(apokemon);
        }

        //opens changeList.csv file to add or delete entries from         Pokemon class
        String changeListfilename = "changeList.csv";
        File changeListFile = new File(changeListfilename);
        Scanner changeScanner = new Scanner(changeListFile);

        //loads text from csv file to be parsed to PokemonNoGaps class
        while(changeScanner.hasNextLine()) {
            String changeLine = changeScanner.nextLine();
            String[] changeStringArray = changeLine.split(", ");
            String action = changeStringArray[0];
            String nameOrId = changeStringArray[1];

            //if changList.csv file line has an "A" in the first spot add this entry to somePokemon
            if(action.equals("A")) {
                int newId = pokedex1.getNewId();
                String name = nameOrId;
                Pokemon somePokemon = new Pokemon(newId, name);
                pokedex1.add(somePokemon);
            }
            //if it has a "D" then send it to PokemonNoGaps class to delete the entry from the array
            else { //"D"
                int someId = Integer.parseInt(nameOrId);
                pokedex1.deleteById(someId);
            }
            //tests the action being taken and the update to the array
            //System.out.println(action + "\t" + nameOrId + "\n");
            System.out.println(pokedex1);

            //*(supposedly)* prints the resulting contents of the array to a new csv file
            String[] pokemonList = changeStringArray;
            try {
                String outputFile1 = "pokedex1.csv";
                FileWriter writer1 = new FileWriter(outputFile1);
                writer1.write(String.valueOf(pokemonList));
            } catch (IOException e) {
                System.out.println("\nError writing to Pokedex1.csv!");
                e.printStackTrace();
            }
        }
        //tests final contents of array after being passed through PokemonNoGaps class
        //System.out.println(pokedex1);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

}

PokemonNoGaps 类文件:

public class PokemonNoGaps implements ChangePokedex {
    private Pokemon[] pokedex = new Pokemon[1];
    private int numElements = 0;
    private static int id = 0;
    // add, delete, search

    @Override
    public void add(Pokemon apokemon) {
        // if you have space
        this.pokedex[this.numElements] = apokemon;
        this.numElements++;
        // if you don't have space
        if(this.numElements == pokedex.length) {
            Pokemon[] newPokedex = new Pokemon[ this.numElements * 2]; // create new array
            for(int i = 0; i < pokedex.length; i++) { // transfer all     elements from array into bigger array
                newPokedex[i] = pokedex[i];
            }
            this.pokedex = newPokedex;
        }
        this.id++;
    }

    public int getNewId() {
        return this.id + 1;
    }
    @Override
    public void deleteById(int id) {
        for(int i = 0; i < numElements; i++) {
            if(pokedex[i].getId() == id) {
                for(int j = i+1; j < pokedex.length; j++) {
                    pokedex[j-1] = pokedex[j];
                }
                numElements--;
                pokedex[numElements] = null;
            }
        }
    }

    public Pokemon getFirstElement() {
        return pokedex[0];
    }
    public int getNumElements() {
        return numElements;
    }
    public String toString() {
        String result = "";
        for(int i = 0; i < this.numElements; i++) {
            result += this.pokedex[i].toString() + "\n";
        }
        return result;
    }
}

异常输出:

1, Bulbasaur
3, Venasaur
4, Charizard
5, Squirtle

我是否使用了错误的文件编写器?我是在错误的时间还是错误地调用了文件编写器?换句话说,我不知道为什么我的输出文件是空的并且没有加载我的数组的内容。谁能帮帮我?

【问题讨论】:

    标签: java arrays csv filewriter


    【解决方案1】:
    String outputFile1 = "pokedex1.csv";
    FileWriter writer1 = new FileWriter(outputFile1);
    

    似乎在您的while 循环中,因此每次都会创建一个新文件。

    要么使用FileWriter(File file, boolean append)构造函数,要么在循环之前创建

    【讨论】:

    • 感谢您指出这一点。从现在开始,当我使用作家时,我会记住这一点!因此,如果我将构造函数放在循环之前,它只会调用一次?
    • 另外,不是每次都创建一个新文件。相反,每次我运行它时都会附加到同一个文件。如何让它每次都重写文件或创建文件的新实例?
    【解决方案2】:

    我在运行此程序时发现了一些问题。如上一个答案中所述,您希望在写入新 pokedx1.csv 的代码部分中将 file append 设置为 true

       try {
            String outputFile1 = "pokedex1.csv";
            FileWriter fileWriter = new FileWriter(prefix+outputFile1, true);
            BufferedWriter bw = new BufferedWriter(fileWriter);
            for(String pokemon : pokedex1.toString().split("\n")) {
                System.out.println(pokemon);
                bw.write(pokemon);
            }
            bw.flush();
            bw.close();
       } catch (IOException e) {
            System.out.println("\nError writing to Pokedex1.csv!");
            e.printStackTrace();
       }
    

    我选择使用缓冲阅读器作为解决方案。我发现的另一个问题是您正在阅读 pokedex.csv 但文件名为 pokemon.csv。

    String pokedexFilename = "pokemon.csv";
    

    我进行了上述更改以解决此问题。

    在旁注中,我注意到您创建了多个扫描仪来读取这两个文件。使用这些类型的资源,在使用完它们后调用 close 方法是一种很好的做法;如下图。

    Scanner pokescanner = new Scanner(pokedexFile);
    // Use scanner code here
    // Once finished with scanner
    pokescanner.close();
    

    【讨论】:

    • 我已经关闭了我正在使用的扫描仪。当我看到这个答案时,我实际上正在这样做。我已将原始文件的名称更改为 pokedex.csv,对那里的混乱感到抱歉。如上所述,我对扫描仪进行了更改,现在我终于得到了要写入文件的内容。好消息和坏消息。首先
    • 好 = 我将正确的信息打印到文件中。坏 = 输出重复了 9 次。它用一行中的所有信息填充顶行,然后在文件的接下来的 8 行中重复。 (例如:1 Bulbasaur3 Venasaur5 Charmeleon...[下一行]1 Bulbasaur3 Venasaur5 Charmeleon...[7 次以上]。它与总共使用的元素数量一致。任何想法为什么会发生这种情况?
    • 我在您的代码中注意到您正在使用 System.out.println 进行调试。您使用什么 IDE 来开发尽可能多的调试模式,这将帮助您在代码运行时跟踪代码。那或者我建议您尝试编写一些 Junit 测试来帮助确保您的代码按照您的预期运行。
    • 我认为主要问题之一是您正在写入循环内的 csv 文件。 while (changeScanner.hasNextLine())我会尝试将问题的每一步分离成一个指定的方法。首先读取文件,然后删除/添加项目,最后一旦您知道要添加/删除文件写入文件(这应该在循环之外完成)。此外,如果您将此代码移到循环之外,那么您可能不想再追加到文件中了。
    • 感谢您的建议!使用单独的方法听起来比我尝试做的要容易。我目前正在使用 Eclipse。其他一切似乎都正常!
    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 2021-10-16
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多