Error Reading and writing files (Java) [closed] - java

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Hi guys i just implemented object files into my program and i am constantly getting the errors (error reading file and problem writing to file) these are 2 errors in my try catch block, when i try to read the file it does not load, saving doesn't work either.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class Stores implements Serializable
{
public static ArrayList<Student> stud1 = new ArrayList<Student>();
public static ArrayList<SubjectTeacher> sTeach1 = new ArrayList<SubjectTeacher>();
private static int iT = 0;
private static int iS = 0;
public static void savet (ArrayList<SubjectTeacher> teachIn, int count)
{
iT = count;
sTeach1 = teachIn;
saveTeachToFile();
}
public static void saves (ArrayList<Student> studIn, int count)
{
iS = count;
stud1 = studIn;
saveStudToFile();
}
public static ArrayList<Student> getStud ()
{
return stud1;
}
public static ArrayList<SubjectTeacher> getTeach ()
{
return sTeach1;
}
public static int getStudSize()
{
return stud1.size();
}
public static int getTeachSize()
{
return sTeach1.size();
}
private static void saveStudToFile()
{
try
{
// create a FileOutputStream object which will handles the writing of the sudent list of objects to the file.
FileOutputStream studentFile = new FileOutputStream("Students.obf");
// the OutputObjectStream object will allow us to write whole objects to and from files
ObjectOutputStream studentStream = new ObjectOutputStream(studentFile);
for(Student item: stud1) // enhanced for loop
// Loop through the list of studentsListIn and for each of these objects, wite them to the file
{
studentStream.writeObject(item);
}
//close the file so that it is no longer accessible to the program
studentStream.close();
}
catch(IOException e)
{
System.out.println("There was a problem writing the File");
}
}
private static void saveTeachToFile()
{
try
{
FileOutputStream teacherFile = new FileOutputStream("Teacher.obf");
ObjectOutputStream teacherStream = new ObjectOutputStream(teacherFile);
for(SubjectTeacher item1: sTeach1) // enhanced for loop
{
teacherStream.writeObject(item1);
}
//close the file so that it is no longer accessible to the program
teacherStream.close();
}
catch(IOException e)
{
System.out.println("There was a problem writing the File");
}
}
public static void loadStudentList()
{
boolean endOfFile = false;
Student tempStudent;
try
{
// create a FileInputStream object, studentFile
FileInputStream studentFile = new FileInputStream("Students.obf");
// create am ObjectImnputStream object to wrap around studentStream
ObjectInputStream studentStream = new ObjectInputStream(studentFile) ;
// read the first (whole) object with the readObject method
tempStudent = (Student) studentStream.readObject();
while (endOfFile != true)
{
try
{
stud1.add(tempStudent);
// read the next (whole) object
tempStudent = (Student) studentStream.readObject();
}
//use the fact that the readObject throws an EOFException to check whether the end of eth file has been reached
catch(EOFException e)
{
endOfFile = true;
}
studentStream.close();
}
}
catch(FileNotFoundException e)
{
System.out.println("File not found");
}
catch(ClassNotFoundException e) // thrown by readObject
/* which indicates that the object just read does not correspond to any class
known to the program */
{
System.out.println("Trying to read an object of an unkonown class");
}
catch(StreamCorruptedException e) //thrown by constructor
// which indicates that the input stream given to it was not produced by an ObjectOutputStream object {
{
System.out.println("Unreadable File Format");
}
catch(IOException e)
{
System.out.println("There was a problem reading the file");
}
}
public static void loadTeacherList()
{
boolean endOfFile = false;
SubjectTeacher tempTeacher;
try
{
FileInputStream teacherFile = new FileInputStream("Teacher.obf");
ObjectInputStream teacherStream = new ObjectInputStream(teacherFile) ;
tempTeacher = (SubjectTeacher) teacherStream.readObject();
while (endOfFile != true)
{
try
{
sTeach1.add(tempTeacher);
// read the next (whole) object
tempTeacher = (SubjectTeacher) teacherStream.readObject();
}
//use the fact that the readObject throws an EOFException to check whether the end of eth file has been reached
catch(EOFException e)
{
endOfFile = true;
}
teacherStream.close();
}
}
catch(FileNotFoundException e)
{
System.out.println("File not found");
}
catch(ClassNotFoundException e) // thrown by readObject
/* which indicates that the object just read does not correspond to any class
known to the program */
{
System.out.println("Trying to read an object of an unkonown class");
}
catch(StreamCorruptedException e) //thrown by constructor
// which indicates that the input stream given to it was not produced by an ObjectOutputStream object {
{
System.out.println("Unreadable File Format");
}
catch(IOException e)
{
System.out.println("There was a problem reading the file");
}
}
}

Well, for one thing, you should edit the question with the correct code so it doesn't get closed. Second, A couple of things could be happening.
The classes you're writing to file aren't serializable
The files are readonly or write protected somehow
Based on the code from your updated question, it looks like you may be confusing which classes need to implement Serializable. The classes that need to implement that are the ones you're actually writing to file (ie SubjectTeacher, etc.).
Check those two, and let me know what you find.
Also, I'd suggest stepping the code and seeing what the exceptions look like at runtime. You'll get a much better idea of what's going on.

Related

How to overwrite a file that is altering an arraylist

I'm writing a program in order to keep track of DVDs in my library. I'm having trouble altering the text file that saves an added or removed DVD object from the arraylist. Whenever I call my save method, which is the one that overwrites the existing text file holding all the information, it will not change it whatsoever. My add and remove methods work fine but it's just the save method which overwrites the file that I'm reading from that will not work. The following code is what I was attempting to use to save the arraylist to the file. My filename is DVDCollection.txt and the boolean variable flag is a static variable used to check whether or not the code which adds or removes an object from the arraylist was reached.
public void save() {
try{
if(flag=true){
FileWriter instream = new FileWriter("DVDCollection.txt",false);
instream.close();
}else{
return;
}
}catch(IOException e){
System.out.println("The file could not be written to!");
}
}
If you are using java 8 or above it's as simple as:
List<String> lines = Arrays.asList("first line", "second line");
try {
Files.write(Paths.get("my-file.txt"), lines);
} catch (IOException e) {
//handle exception
}
Make sure you provide the right path!
Not sure, why this method should save an array list, as the actual code that writes to this file is missing. Here is simple test, let's start here:
import java.io.*;
import java.util.*;
public class FileSaveTest {
public static void main(String[] args) {
FileSaveTest test = new FileSaveTest();
test.fill();
test.save();
}
public void fill() {
arrayList.add("My disc 1");
arrayList.add("My disc 2");
arrayList.add("Another disc");
}
public void save() {
try {
if(flag) { // you dont need ==true
FileWriter instream = new FileWriter("DVDCollection.txt",false);
for (String entry : arrayList) {
instream.write(entry + "\n");
}
instream.close();
} else {
return;
}
} catch(IOException e) {
System.out.println("The file could not be written to!");
}
}
private ArrayList<String> arrayList = new ArrayList<>();
private static boolean flag = true;
}
Next, it's not very good, to close the file in such manner. If an exception occurs while writing, the file will not be closed. instream.close() should be put into the "finally" block. This block will be executed in any case, regardless of whether an exception occurred or the return keyword met:
public void save() {
Writer instream = null;
try {
if(flag) { // you dont need ==true
instream = new FileWriter("DVDCollection.txt",false);
for (String entry : arrayList) {
instream.write(entry + "\n");
}
} else {
return;
}
} catch(IOException e) {
System.out.println("The file could not be written to!");
} finally {
try {
if (instream != null)
instream.close();
} catch (IOException e) {
System.err.println("Exception during close");
}
}
}
Or, if you are using java 7, you can use try-with-resources syntax:
public void save() {
if(flag) { // you dont need ==true
try (Writer instream = new FileWriter("DVDCollection.txt",false)) {
for (String entry : arrayList)
instream.write(entry + "\n");
} catch(IOException e) {
System.out.println("The file could not be written to!");
}
} // you dont need "return else { return; }" anymore
}

How to get array.length after it has been deserialized [duplicate]

This question already has answers here:
why does the catch block give an error with variable not initialized in Java
(7 answers)
Closed 6 years ago.
So, I'm working on a project that automates everything from character sheets to dice rolls for a table top RPG I like to play. I'm trying to store character data (character name, 2 arrays of stats, and 2 arrays of those stat values) that can be accessed at the start of executing the app. This has been very helpful so far.
However, I'd also like to display the name and stats so the user can confirm that this is the character data they want to use. And I'm having trouble displaying the data in a readable format. Here's my code (you'll find the problem I'm having toward the bottom, although if you see anything else that could be optimized along the way, I would appreciate any feedback :-)":
import java.io.*;
import javax.swing.JOptionPane;
public class fengShuiFiles implements Serializable {//start class
private FileOutputStream outFile;
private ObjectOutput objectWriter;
private FileInputStream inFile;
private ObjectInputStream objectReader;
public void WriteFile(String fileNameIn, String[] sArray1, String[] sArray2,
String[] sArray3, String[] sArray4) {
try {
outFile = new FileOutputStream(fileNameIn + ".txt", true);
objectWriter = new ObjectOutputStream(outFile);
objectWriter.writeObject(sArray1);
objectWriter.writeObject(sArray2);
objectWriter.writeObject(sArray3);
objectWriter.writeObject(sArray4);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "I/O occurred during a write operation\nFor more",
"information see console output.",
"Read File", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
} // End try/catch
} // End Open
//not sure if I'll need this. Keeping it for now just in case
//public void writeRecords(String textRecords)
//{
// outFile.close();
// pw.println(textRecords);
//} // End WriteRecords
public void ReadFile(String fileNamein) throws FileNotFoundException {
fengShuiFiles[] sArray1, sArray2, sArray3, sArray4;
try {
inFile = new FileInputStream(fileNamein + ".txt");
objectReader = new ObjectInputStream(inFile);
sArray1 = (fengShuiFiles[]) objectReader.readObject();
sArray2 = (fengShuiFiles[]) objectReader.readObject();
sArray3 = (fengShuiFiles[]) objectReader.readObject();
sArray4 = (fengShuiFiles[]) objectReader.readObject();
} catch (IOException | ClassNotFoundException e) {
JOptionPane.showMessageDialog(null, "I/O error occurred opening a",
"file\nFor more information see console output.",
"Read File", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
} // End try/catch
for (int x = 0; x < sArray1.length; x++) {
}
}
public void closeFile() {
try {
outFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // End closeFile
}//end class
So, that sArray1.length in the for statement toward the bottom? It's coming up with an error message saying that sArray1 may not have been initialized. And I'm having trouble figuring out why, and how I can get that length so I can print out the arrays in a readable manner. Does anyone have any ideas? Thanks.
You need to initialize local variables. If an exception occurs, it's possible that some or all of the arrays aren't initialized and the compiler won't allow that.
The easiest way to get rid of the error is to initialize the arrays to null, but your program has a logic problem. You're catching the exceptions and continuing, even though there's no way your program can work correctly after that. You should instead throw the exceptions out of the readFile() method and then most likely exit the program. You could also continue as if the file didn't exist, but at least show a warning about it.
You always have to initialize variables in java. You do this in your try block, but if an exception occurs, the array will not have been initialized.
You can move the for loop to the try block:
public void ReadFile(String fileNamein) throws FileNotFoundException {
fengShuiFiles[] sArray1, sArray2, sArray3, sArray4;
try {
...
for(int x = 0; x < sArray1.length; x++) {
}
} catch (IOException | ClassNotFoundException e) {
...
} // End try/catch
}
Or use a default value to initialize the array in the catch block:
public void ReadFile(String fileNamein) throws FileNotFoundException {
fengShuiFiles[] sArray1, sArray2, sArray3, sArray4;
try {
...
} catch (IOException | ClassNotFoundException e) {
...
sArray1 = new fengShuiFiles[0]; // Some default value.
} // End try/catch
for(int x = 0; x < sArray1.length; x++) {
}
}
Something that might be more convenient though, is to return the read arrays, and do something with them in the calling method.
For instance:
public Optional<fengShuiFiles[][]> ReadFile(String fileNamein) throws FileNotFoundException {
try {
fengShuiFiles[] sArray1, sArray2, sArray3, sArray4;
// read the file
return Optional.of(new fenShuiFiles[][]{ sArray1, sArray2, sArray3, sArray4 });
} catch (IOException | ClassNotFoundException e) {
...
return OPtional.empty();
}
}
Then in some other method:
Optional<fengShuiFiles[][]> ret = ReadFile(...);
if(ret.isPresent()) {
for(fengShuiFiles[] arr : ret.get()) {
System.out.println(Arrays.toString(arr)); // Print here
}
}

How do I save states to a file and keep the file safe?

I'm trying to create save states for my game, not so much for where your game was left but something simple like score boards. The format would be something like this:
Wins: 5
Losses: 10
GamesPlayed: 15
I need to be able to access the file, and depending on whether the player won/lost it will append +1 to the value in the file.
What would be the best way to go about this? I've heard of a bunch of different ways to save data, for example XML, but aren't those overkill for the size of my data?
Also, I do want to keep this file safe from the users being able to go into the files and change the data. Would I have to do some sort of encryption? And, if the user removes the file and replaces it with an empty one can't they technically reset their values?
You can use plain serialization/deserialization for this. In order to serialize/deserialize a class, it must implement the Serializable interface. Here's a example to start with:
public class Score implements Serializable {
private int wins;
private int loses;
private int gamesPlayed;
//constructor, getter and setters...
}
public class ScoreDataHandler {
private static final String fileName = "score.dat";
public void saveScore(Score score) {
ObjectOutputStreamout = null;
try {
out = new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject(score);
} catch (Exception e) {
//handle your exceptions...
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ioe) {
}
}
}
}
public Score loadScore() {
ObjectInputStreamin = null;
Score score = null;
try {
in = new ObjectInputStream(new FileInputStream(fileName));
score = (Score)in.readObject();
} catch (Exception e) {
//handle your exceptions...
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ioe) {
}
}
}
return score;
}
}

A properties file I created in the 1st run gets blanked in the 2nd run

Okay, I'm trying to create a custom client for Minecraft (don't worry, my question has nothing to do with Minecraft in particular), and I added an abstract class to manage a configuration file using Java's built-in Properties system. I have a method that loads a properties file or creates it if it doesn't already exist. This method is called at the beginning of all my other methods (although it only does anything the first time its called).
The properties file gets created just fine when I run Minecraft the first time, but somehow when I run it the second time, the file gets blanked out. I'm not sure where or why or how I'm wiping the file clean, can someone please help me? Here's my code; the offending method is loadConfig():
package net.minecraft.src;
import java.util.*;
import java.util.regex.*;
import java.io.*;
/**
* Class for managing my custom client's properties
*
* #author oxguy3
*/
public abstract class OxProps
{
public static boolean configloaded = false;
private static Properties props = new Properties();
private static String[] usernames;
public static void loadConfig() {
System.out.println("loadConfig() called");
if (!configloaded) {
System.out.println("loading config for the first time");
File cfile = new File("oxconfig.properties");
boolean configisnew;
if (!cfile.exists()) {
System.out.println("cfile failed exists(), creating blank file");
try {
configisnew = cfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
configisnew=true;
}
} else {
System.out.println("cfile passed exists(), proceding");
configisnew=false;
}
FileInputStream cin = null;
FileOutputStream cout = null;
try {
cin = new FileInputStream(cfile);
cout = new FileOutputStream(cfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!configisnew) { //if the config already existed
System.out.println("config already existed");
try {
props.load(cin);
} catch (IOException e) {
e.printStackTrace();
}
} else { //if it doesn't exist, and therefore needs to be created
System.out.println("creating new config");
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
try {
props.store(cout, "OXGUY3'S CUSTOM CLIENT\n\ncloak_url is the URL to get custom cloaks from\nnames are the usernames to give cloaks to\n");
cout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
String names = props.getProperty("names");
System.out.println("names: "+names);
try {
usernames = Pattern.compile(", ").split(names);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("usernames: "+Arrays.toString(usernames));
configloaded=true;
}
}
public static boolean checkUsername(String username) {
loadConfig();
System.out.println("Checking username...");
for (int i=0; i<usernames.length; i++) {
System.out.println("comparing "+username+" with config value "+usernames[i]);
if (username.startsWith(usernames[i])){
System.out.println("we got a match!");
return true;
}
}
System.out.println("no match found");
return false;
}
public static String getCloakUrl() {
loadConfig();
return props.getProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
}
}
If it's too hard to read here, it's also on Pastebin: http://pastebin.com/9UscXWap
Thanks!
You are unconditionally creating new FileOutputStream(cfile). This will overwrite the existing file with an empty one. You should only invoke the FileOutputStream constructor when writing a new config file.
if (configloaded)
return;
File cfile = new File("oxconfig.properties");
try {
if (cfile.createNewFile()) {
try {
FileOutputStream cout = new FileOutputStream(cfile);
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://...");
...
cout.flush();
} finally {
cout.close();
}
} else {
FileInputStream cin = new FileInputStream(cfile);
try {
props.load(cin);
} finally {
cin.close();
}
}
configloaded=true;
} catch(IOException ex) {
e.printStackTrace();
}

Infinite Loop when looping through FileInputStream

Alright, so I am writing a Java application to import a csv file and then loop through the results, and load them into an array. I am importing the file correctly because it doesn't through an Exception. My issues is that when I try to count the number of records in the FileInputStream I am trapped in an infinite loop. What could be the issue here. Heres the code:
This is my class with a Main method which calls go():
public void go() {
pop = new PopularNames();
popGui = new PopularNamesGui();
String file = popGui.userInput("Enter the correct name of a file:");
pop.setInputStream(file);
pop.getNumberOfNames();
}
This is the class PopularNames (pop), and in the below method I am setting the inputStream var to a new FileINputStream. The file name is provided by the user.
public void setInputStream(String aInputStream) {
try {
inputStream = new Scanner(new FileInputStream(aInputStream));
} catch (FileNotFoundException e) {
System.out.println("The file was not found.");
System.exit(0);
}
}
This is the trouble method. Where I am simply looping through the FileInputStream and counting the number of records:
public void getNumberOfNames() {
while (this.inputStream.hasNext()) {
fileDataRows++;
}
}
public void getNumberOfNames() {
while (this.inputStream.hasNext()) {
inputStream.nextLine(); // Need to read it so that we can go to next line if any
fileDataRows++;
}
}

Categories