我这样做是为了学校的作业,所以我不寻找一个明确的答案,更多的是关于我的文件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流输出的是空数组列表。