Java无法将ArrayList输出到现有文件

时间:2017-04-05 16:59:40

标签: java arraylist file-io exception-handling

我这样做是为了学校的作业,所以我寻找一个明确的答案,更多的是关于我的文件I / O出了什么问题的一些信息和指示。 / p>

我正在尝试将一个ArrayList对象写入一个文件,并让它覆盖当前在ArrayList中的内容。到目前为止,我已经尝试了两件事。第一个是代码

    public static void saveToDo(String fileName, ArrayList<ToDo> td)
{
    try{
    FileOutputStream objectFileStream = new FileOutputStream(fileName);
    ObjectOutputStream oos = new ObjectOutputStream(objectFileStream);
    oos.writeObject(td);
    oos.close();
    objectFileStream.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

目前,当我运行它(使用GUI)并保存时,它会抛出

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at cst8284.assignment1.TaskManager.findFirstValue(TaskManager.java:335)
at cst8284.assignment1.TaskManager.getFile(TaskManager.java:361)
at cst8284.assignment1.TaskManager.lambda$7(TaskManager.java:428)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at 
com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Unknown Source)

这让我相信它打印了一个空的ArrayList,所以当它回读时,它无法找到索引,然后终止。

我下一次修复的尝试是

    public static void saveToDo(String fileName, ArrayList<ToDo> td)
{
    try{
    FileOutputStream objectFileStream = new FileOutputStream(fileName);
    ObjectOutputStream oos = new ObjectOutputStream(objectFileStream);
    for(ToDo tdArray : td){
    oos.writeObject(tdArray);
    }
    oos.close();
    objectFileStream.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

据我所知,实际上并没有改变任何东西。当我单击“保存”并重新加载文件时,旧输入仍然存在,我想要保存的输入无处可寻。我此刻不知所措,我一直在为此坚持4个小时。我将假设问题在于我对文件I / O如何工作有一个基本的误解,但是任何指向正确方向的内容都将非常感激。

下面是使用这些文件的两个文件。为了便于阅读,我省略了import语句。

public class TaskManager extends Application{

private ArrayList<ToDo> toDoArray;
private static int currentToDoElement;
private Stage primaryStage;
//Dave Houtman, March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
@Override
public void start(Stage primaryStage) {
    setPrimaryStage(primaryStage);
    getPrimaryStage().setTitle("To Do List");
    getPrimaryStage().setScene(getSplashScene());
    //getPrimaryStage().setScene(getDefaultScene("Click here to open"));
    getPrimaryStage().show();
}
//Dave Houtman, March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
public void setPrimaryStage(Stage PrimaryStage)
{
    this.primaryStage = PrimaryStage;
}

public Stage getPrimaryStage()
{
    return this.primaryStage;
}
public Scene getSplashScene()
{   
    Label defaultLabel = new Label("())======D");
    Path path = new Path();
    path.getElements().add (new MoveTo (-250f, -157f));
    path.getElements().add (new CubicCurveTo (300f, 250f, -100f, 50f, 440f, 80f));
    PathTransition pathT = new PathTransition();
    pathT.setDuration(Duration.millis(5000));
    pathT.setNode(defaultLabel);
    pathT.setPath(path);
    pathT.setOrientation(OrientationType.ORTHOGONAL_TO_TANGENT);
    pathT.setCycleCount(Timeline.INDEFINITE);
    //(Kostovarov, 2012)
    pathT.setAutoReverse(true);
    //(Class PathTransition, n.d)
    FadeTransition fadeT = new FadeTransition(Duration.millis(500), defaultLabel);
    fadeT.setFromValue(1.0);
    fadeT.setToValue(0.0);
    fadeT.setCycleCount(Timeline.INDEFINITE);
    fadeT.setAutoReverse(true);
    //(Kostovarov, 2012)
    ParallelTransition paralT = new ParallelTransition(pathT, fadeT);
    paralT.play();
    //(Class ParallelTransition, n.d)
    StackPane defaultPane = new StackPane();
    defaultPane.getChildren().add(defaultLabel);
    Scene defaultScene = new Scene(defaultPane, 900, 500);
    defaultPane.setOnMouseClicked((e) -> {
        getFile();
    });
    return defaultScene;

}

public static void main(String[] args) {
    Application.launch(args);
}

public ArrayList<ToDo> getToDoArray()
{
    return toDoArray;
}

public void setToDoArray(ArrayList<ToDo> toDoArray){
    this.toDoArray = toDoArray;
}

public Scene getToDoScene(ToDo td)
{
    Scene toDoScene = new Scene(getToDoPane(td), 900, 500);
    return toDoScene;
}
public Pane getToDoPane(ToDo td)
{
    BorderPane rootNode = new BorderPane();                                             
    VBox vbLeft = new VBox();                                                   
    vbLeft.setMinWidth(120);                                                    
    VBox vbRight = new VBox();                                                  
    vbRight.setMinWidth(120);       

    rootNode.setLeft(vbLeft);                                                   
    rootNode.setRight(vbRight);                     
    //(Houtman, 2017)
    rootNode.setBottom(getBottomPane());
    rootNode.setCenter(getCenterInfoPane(td));
    rootNode.setTop(getMenuBar());
    return rootNode;
}

public static void setToDoElement(int element)
{
    currentToDoElement = element; 
}

public static int getToDoElement()
{
    return currentToDoElement;
}

public Pane getCenterInfoPane(ToDo td)
{
    GridPane infoPane = new GridPane(); 
    infoPane.setVgap(5);
    infoPane.setHgap(3);
    infoPane.setAlignment(Pos.CENTER);
    //(Gordon, 2013)
    Label lblTask = new Label("Task");
    GridPane.setConstraints(lblTask, 2, 0);
    TextField tfTask = new TextField(td.getTitle());
    GridPane.setColumnSpan(tfTask, 4);
    GridPane.setConstraints(tfTask, 5, 0);
    //(Houtman, 2017)
    Label lblSubject = new Label("Subject");
    GridPane.setConstraints(lblSubject, 2, 6);
    TextArea taSubject = new TextArea(td.getSubject());
    GridPane.setColumnSpan(taSubject, 4);
    GridPane.setConstraints(taSubject, 5, 6);
    //(Houtman, 2017)
    Label lblDate = new Label("Due Date");
    GridPane.setConstraints(lblDate, 2, 12);
    TextField tfDate = new TextField(td.toString());
    GridPane.setColumnSpan(tfDate, 4);
    GridPane.setConstraints(tfDate, 5, 12);
    //(Houtman, 2017)
    Label lblPriority = new Label("Priority");
    GridPane.setConstraints(lblPriority, 2, 20);
    //(Class GridPane, n.d)
    final ToggleGroup radioGroup = new ToggleGroup();
    RadioButton rButton1 = new RadioButton("1");
    rButton1.setToggleGroup(radioGroup);
    GridPane.setConstraints(rButton1, 6, 20);
    RadioButton rButton2 = new RadioButton("2");
    rButton2.setToggleGroup(radioGroup);
    GridPane.setConstraints(rButton2, 7, 20);
    RadioButton rButton3 = new RadioButton("3");
    GridPane.setConstraints(rButton3, 8, 20);
    rButton3.setToggleGroup(radioGroup);
    //(Redko, 2013)
    infoPane.getChildren().addAll(lblTask, lblSubject, lblDate, lblPriority, tfTask, taSubject, tfDate, rButton1, rButton2, rButton3);
    return infoPane;
}

public Pane getBottomPane()
{

    Button btnFirst = new Button("|<<");
    btnFirst.setOnMouseClicked((e) -> {
        setToDoElement(findFirstValue());
        getPrimaryStage().setScene(getToDoScene(getToDoArray().get(currentToDoElement)));
    });
    if(btnBeginDisableCheck() || prevEmptyCheck())
    {
        btnFirst.setDisable(true);
    }
    Button btnLast = new Button(">>|");
    btnLast.setOnMouseClicked((e) -> {
        setToDoElement(findFinalValue());
        getPrimaryStage().setScene(getToDoScene(getToDoArray().get(currentToDoElement)));
    });
    if(btnEndDisableCheck() || nextEmptyCheck())
    {
        btnLast.setDisable(true);
    }
    Button btnNext = new Button(">>");
    btnNext.setOnMouseClicked((e) -> {
        setToDoElement(findNextValue());
        getPrimaryStage().setScene(getToDoScene(getToDoArray().get(currentToDoElement)));
    });
    if(btnEndDisableCheck() || nextEmptyCheck())
    {
        btnNext.setDisable(true);
    }
    Button btnPrev = new Button("<<");
    btnPrev.setOnMouseClicked((e) -> {
        setToDoElement(findPrevValue());
        getPrimaryStage().setScene(getToDoScene(getToDoArray().get(currentToDoElement)));
    });
    if(btnBeginDisableCheck() || prevEmptyCheck())
    {
        btnPrev.setDisable(true);
    }
    //Houtman, D (n.d) Module 04: Intro to JavaFX [PowerPoint Slides]
    //Retrieved from https://blackboard.algonquincollege.com/bbcswebdav/pid-2266545-dt-content-rid-8023117_1/courses/17W_CST8284_300/17W_Module%2004%20-%20Introduction%20to%20JavaFX%287%29.pdf
    HBox hbBottom = new HBox();
    hbBottom.setAlignment(Pos.CENTER);
    hbBottom.setSpacing(15);
    //(Hbox, n.d)
    hbBottom.getChildren().addAll(btnFirst, btnPrev , btnNext, btnLast);
    return hbBottom;
}

public boolean btnBeginDisableCheck()
{
    return(getToDoElement() == 0);
}

public boolean btnEndDisableCheck()
{
    return(getToDoElement() == getToDoArray().size() - 1);
}

public boolean nextEmptyCheck()
{
    int startingElement = getToDoElement() + 1;
    if(startingElement >= getToDoArray().size())
    {
        return true;
    }
    while(getToDoArray().get(startingElement).isEmptySet())
    {
        startingElement++;
        if(startingElement == getToDoArray().size())
        {
            return true;
        }

    }
    return false; 
}

public boolean prevEmptyCheck()
{
    int startingElement = getToDoElement() - 1;
    while(getToDoArray().get(startingElement).isEmptySet())
    {
        startingElement--;
        if(startingElement <= -1)
        {
            return true;
        }   
    }
    return false;
}

public int findNextValue()
{
    int nextValue = getToDoElement();
    do
    {
        nextValue++;
    }while(getToDoArray().get(nextValue).isEmptySet());
    return nextValue;
}

public int findPrevValue()
{
    int PrevValue = getToDoElement();
    do
    {
        PrevValue--;
    }while(getToDoArray().get(PrevValue).isEmptySet());
    return PrevValue;
}

public int findFinalValue()
{
    int finalValue = getToDoArray().size() - 1;
    while(getToDoArray().get(finalValue).isEmptySet())
    {
        finalValue--;
    }
    return finalValue;
}

public int findFirstValue()
{
    int firstValue = getToDoArray().size() - getToDoArray().size();
    while(getToDoArray().get(firstValue).isEmptySet())
    {
        firstValue++;
    }
    return firstValue;
}   

public void getFile()
{
    FileChooser fc = new FileChooser();
    fc.setTitle("Open ToDO File");
    fc.setInitialDirectory(new File("D:\\"));
    //fc.setInitialDirectory(new File("C:\\Users\\Alec\\Desktop"));
    //refernce docs
    fc.getExtensionFilters().addAll(
            new ExtensionFilter("Quiz Files", "*.todo"),
            new ExtensionFilter("All Files", "*.*")
            );
    File todoFile = fc.showOpenDialog(primaryStage);   //turn this into a method to be used down below for saving to the file.
    //(Houtman, 2017)
    if(checkExentsion(todoFile))
    {
        FileUtils utils = new FileUtils();      
        FileUtils.setAbsPath(todoFile);
        utils.getToDoArray(todoFile.getAbsolutePath());  //possible redundancy
        setToDoArray(utils.getToDoArray(FileUtils.getAbsPath()));
        setToDoElement(findFirstValue());
        getPrimaryStage().setScene(getToDoScene(getToDoArray().get(getToDoElement())));
        getPrimaryStage().show();
        System.out.print(getToDoArray().size());    
    }
    else
    {
        getErrorStage();
    }       
}

public Stage getErrorStage()
{
    Stage errorDialogue = new Stage();
    errorDialogue.setScene(getErrorScene());
    errorDialogue.setTitle("Invalid .todo file selected");
    errorDialogue.setResizable(false);
    errorDialogue.initStyle(StageStyle.UTILITY);
    //reference needed, stackoverflow
    errorDialogue.show();
    return errorDialogue;

}

public Scene getErrorScene()
{

    HBox hbox = new HBox();
    hbox.setAlignment(Pos.CENTER);
    hbox.setSpacing(50.5);
    Button btnOk = new Button("OK");
    btnOk.setOnMouseClicked((e -> {
        getFile();
    }));
    HBox.setMargin(btnOk, new Insets(0,0,25,0));
    //reference needed, docs
    Button btnCancel = new Button("Cancel");
    btnCancel.setOnMouseClicked((e -> {
        Platform.exit();
    }));
    hbox.getChildren().addAll(btnOk, btnCancel);
    HBox.setMargin(btnCancel, new Insets(0,0,25,0));
    //referned docs
    Label errorLabel = new Label("You did not select a valid .todo file. Please select a valid .todo file. Selecting cancel will exit the program.");
    BorderPane errorPane = new BorderPane();
    errorPane.setCenter(errorLabel);
    errorPane.setBottom(hbox);
    Scene errorScene = new Scene(errorPane, 700, 150);

    return errorScene;

}

public boolean checkExentsion(File fName)
{
    String extension = fName.getName().substring(fName.getName().lastIndexOf("."));
    return (extension.equals(".todo"));
    //reference here
}

public MenuBar getMenuBar()
{
    MenuBar mBar = new MenuBar();
    mBar.prefWidthProperty().bind(primaryStage.widthProperty());
    Menu fileMenu = new Menu("File");
    MenuItem openMenu = new MenuItem("Open");
    openMenu.setOnAction((e) -> {
        getFile();
    });
    MenuItem saveMenu = new MenuItem("Save");
    saveMenu.setOnAction((e) -> {
        FileUtils.saveToDo(FileUtils.getAbsPath(), getToDoArray());
    });
    MenuItem addTD = new MenuItem("Add ToDo");
    MenuItem removeTD = new MenuItem("Remove ToDo");
    MenuItem exitMenu = new MenuItem("Exit");
    exitMenu.setOnAction(actionEvent -> Platform.exit());

    fileMenu.getItems().addAll(openMenu, saveMenu, addTD, removeTD,
            new SeparatorMenuItem(), exitMenu);
    mBar.getMenus().add(fileMenu);
    return mBar;
    //reference here
}

}

和实际的文件I / O类     公共类FileUtils {

private static String relPath = "ToDoList.todo";
                    //Houtman, D. March 17th, 2017, Assignment1.zip [Zip File Download]. 
                    //Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
public ArrayList<ToDo> getToDoArray(String fileName) {
    ArrayList<ToDo> toDoArray = new ArrayList<>();
    try
    {
        FileInputStream objectFileStream = new FileInputStream(fileName);
        ObjectInputStream ois = new ObjectInputStream(objectFileStream);
        //Houtman, D. March 17th, 2017, File I/O Part 2 [MP4 File]. 
        //Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_2178319_1&mode=reset
        Object obj = null;
        while ((obj = ois.readObject()) != null) {
            if (obj instanceof ToDo) {
            ToDo newObject = (ToDo) obj;
            toDoArray.add(newObject);
            }
        }
        //reference stackoverflow
        ois.close();
        objectFileStream.close();
    }

    catch(ClassNotFoundException | IOException e){
        e.printStackTrace();
    }
    //(Houtman, 2017)
    return toDoArray;
}



public static String getAbsPath() {
    return relPath;
}
//Houtman, D. March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
public static String getAbsPath(File f) {
    return f.getAbsolutePath();
}
//Houtman, D. March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
public static void setAbsPath(File f) { 
    relPath = (fileExists(f))? f.getAbsolutePath():""; 
}
//Houtman, D. March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset
public static Boolean fileExists(File f) {
    return (f != null && f.exists() && f.isFile() && f.canRead());
}
//Houtman, D. March 17th, 2017, Assignment1.zip [Zip File Download]. 
//Retrieved from https://blackboard.algonquincollege.com/webapps/blackboard/content/listContent.jsp?course_id=_345505_1&content_id=_1930549_1&mode=reset

public static void saveToDo(String fileName, ArrayList<ToDo> td)
{
    try{
    FileOutputStream objectFileStream = new FileOutputStream(fileName);
    ObjectOutputStream oos = new ObjectOutputStream(objectFileStream);
    for(ToDo tdArray : td){
    oos.writeObject(tdArray);
    }
    oos.close();
    objectFileStream.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

}

编辑:关于被标记为重复,我已经尝试了该线程中提供的步骤无济于事。我的代码在本地发生了一些事情,我从根本上很难理解。将此标记为重复对我没有任何意义。 (或其他任何有类似问题的人。)

EDIT2:我想重申,我已经得出了自己的结论,因为我认为根本问题是存在的。就堆栈跟踪而言,我相信当它运行findFirst方法时,它什么都没找到,这就是它抛出异常的原因,但我相信它会引发异常,因为objectoutput流输出的是数组列表。

0 个答案:

没有答案