java.io.StreamCorruptedException: In java Code - java

How to read the object in to the file i am use the ObjectInputStream and ObjectOutputStream
class to read and write the Object of the my custom class Student for this demo.
Code to Write and read use::
try
{
if(af.filepath==null || af.filepath=="")//file path
{
JOptionPane.showMessageDialog(null, "Please Set File Path", "File Path Error", JOptionPane.ERROR_MESSAGE);
}
else
{
FileOutputStream fs=new FileOutputStream(af.filepath,true);
ObjectOutputStream fo=new ObjectOutputStream(fs);
fo.writeObject(af.s);//write the Super Class Object
fo.close();
}
}
catch (Exception ex)
{
System.out.println(ex);
}
---------------------------------------------------------------------------------
try
{
if(af.filepath==null || af.filepath=="")//file path have whole path of the file
{
JOptionPane.showMessageDialog(null, "Please Set File Path", "File Path Error", JOptionPane.ERROR_MESSAGE);
}
else
{
Student sp;
FileInputStream fs=new FileInputStream(af.filepath);
ObjectInputStream fo=new ObjectInputStream(fs);
while ((sp=(Student)fo.readObject())!=null)
{
sp.set();//for print object
}
fo.close();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
using this i am read first object in the file but after that raise an error

You have written one object and you are attempting to read multiple objects. When you attempt to read the second one, you are bound to get an exception.
If you want to read back an indefinite number of objects ... like that ... I suggest you write a null to the stream:
fo.writeObject(null);
(The javadoc doesn't say you can do this, but the Java Object Serialization spec says you can; see http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#933 ... step 3.)
The other problem (and this is what causes the corruption) is that you are attempting to append serialized objects to an existing file. That's not going to work. The serialization protocol says that a stream consists of a header followed by zero or more serialized objects ... and then the end of file. If you append one stream to another (e.g. FileOutputStream(path, true), the extra header is going to make the combined file readable at the point where the appended stuff starts.

Related

Java, how to write or add instead of overwriting a textfile?

I wonder why my program overwrites existing text in the textfile instead of adding a new line of text?
public class WriteToFile {
public void registerTrainingSession(Customer customer) {
Path outFilePath = Paths.get("C:\\Users\\Allan\\Documents\\Nackademin\\OOP\\Inlämningsuppgift2\\visits.txt");
try (BufferedWriter save = Files.newBufferedWriter(outFilePath)) {
String trainingSession = String.format("Member: %s %s\nPersonalnumber: %s\nTraining session date: %s\n", customer.getFirstName(),
customer.getLastName(), customer.getPersonalNumber(), LocalDate.now());
save.write(trainingSession);
save.flush();
}
catch (NullPointerException e) {
JOptionPane.showMessageDialog(null, "Customer info is missing!");
}
catch (IOException e) {
JOptionPane.showMessageDialog(null, "File could not be created.");
}
}
}
The code overwrites the file because you didn't specify an OpenOption on the newBufferedWriter() call.
As the javadoc says:
If no options are present then this method works as if the CREATE, TRUNCATE_EXISTING, and WRITE options are present. In other words, it opens the file for writing, creating the file if it doesn't exist, or initially truncating an existing regular-file to a size of 0 if it exists.
Try:
Files.newBufferedWriter(outFilePath, StandardOpenOption.CREATE,
StandardOpenOption.APPEND,
StandardOpenOption.WRITE)
Or if the file must already exist, failing if it doesn't:
Files.newBufferedWriter(outFilePath, StandardOpenOption.APPEND,
StandardOpenOption.WRITE)
To write a new file, failing if it already exists
Files.newBufferedWriter(outFilePath, StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE)

ObjectOutputStream writing array to file with inherited classes not writing to file

My assignment is to save a list of employees as a binary file (and later read from it). I'm working on the output portion now, below is the block of the function that is in question. This function does have about 10 more lines but they edit things on the TextField arraylist.
The Employee class is the parent of both the Supervisor and Secretary classes. all is the ArrayList that holds all the employee, secretary, and employee objects.
I'm using netbeans 8.0.2, when the program runs and I click the save button in the gui (onActionEvent() is this function) there are no compiler errors. The "IO Error" or "No Permissions..." doesn't output. Ive tried saving both with and without the employees.dat file being already created.
I'm not really sure what to do at this point, I contemplated saving each object as a the collection of int, String, etc but that's dumb, it should be able to work this way... right?
EDIT:
Employee, Supervisor, and Secretary are all Serializable.
private void saveChanges(ArrayList<Employee> all, ArrayList<TextField> text, int index) {
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
output.flush();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
EDIT:
I have edited the try-catch to this code...
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
output.writeObject(all);
output.flush();
output.close();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
Still not writing to file. I have permissions in the folder the .java files are in.
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
Change true to false, or remove it. You can't append to files created as object output streams, at least not like this, and it's debatable whether you're even supposed to be doing so.
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
Change this entire mess to this:
output.writeObject(all);
If this still doesn't work there must have been an exception somewhere, and you're just going to have to find it, print it, and post it. Edit it into your question. Or else you're looking at the wrong file.
NB you will also have to change the code that reads the file, to just read the list in a single readObject() call.
By any chance are you happening to write an applet or JNLP without appropriate permissions?
do you have write access to the folder that you are outputting the file ? (which in this case is the directory that the program is running in. )
I would recomend calling io.printStackTrace() and se.printStackTrace(); in the exception handlers to provide significantly more information about the exceptions.
At the end of the file writing also dont forget to call output.close() to ensure that the stream is closed properly, the tail of the data is written and there are no left over open file handles on your system.

java.nio.file.AccessDeniedException when reading a file

I want to read file content using this code:
String content = new String(Files.readAllBytes(Paths.get("/sys/devices/virtual/dmi/id/chassis_serial")));
On some systems this file is not present or it's empty. How I catch this exception? I want to print message "No file" when there is no file and there is no value.
The AccessDeniedException can be thrown only when using the new file API. Use an inputStream to open a stream from the source file so that you could catch that exception.
Try with this code :
try
{
final InputStream in = new Files.newInputStream(Path.get("/sys/devices/virtual/dmi/id/chassis_serial"));
} catch (FileNotFoundException ex) {
System.out.print("File not found");
} catch(AccessDeniedException e) {
System.out.print("File access denied");
}
Try to use filter file.canRead()) to avoid any access exceptions.
Create a File object and check if it exists.
If it does then it's safe to convert that file to a byte array and check that the size is greater then 0. If it is convert it to a String. I added some sample code below.
File myFile = new File("/sys/devices/virtual/dmi/id/chassis_serial");
byte[] fileBytes;
String content = "";
if(myFile.exists()) {
fileBytes = File.readAllBytes(myfile.toPath);
if(fileBytes.length > 0) content = new String(fileBytes);
else System.out.println("No file");
else System.out.println("No file");
I know it's not the one liner you were looking for. Another option is just to do
try {
String content = new String(Files.readAllBytes(Paths.get("/sys/devices/virtual/dmi/id/chassis_serial")));
} catch(Exception e) {
System.out.print("No file exists");
}
Read up on try catch blocks here like MrTux suggested, as well as java Files and java io here.

IOException and NullPointerException from ObjectInputStream

I'm writing a small program for an assignment and part of it involves reading from a file using ObjectInputStream. I've run into a brick wall because I keep getting errors when trying to close the file in the finally block as well as a NullPointerException but I cannot understand why. Any help is much appreciated! I have checked already and the file path is correct, so it is able to find the file.
Example file:
hello || apples, acai berry, bananas || shopping || 0.0005 || yes
public Disease[] readInCancers() {
Disease[] cancerList = null;
try {
FileInputStream fis = new FileInputStream(myData);
BufferedInputStream bis = new BufferedInputStream(fis);
ois = new ObjectInputStream(bis);
while(true) {
Disease disease = null;
try {
disease = (Disease)ois.readObject();
} catch (EOFException eofx) {
break;
}
if (cancerList == null || cancerList.length == 0) {
cancerList = new Disease[1];
cancerList[0] = disease;
} else {
Disease[] newList = new Disease[cancerList.length + 1];
System.arraycopy(cancerList, 0, newList, 0, cancerList.length);
newList[cancerList.length] = disease;
cancerList = newList;
}
}
} catch (FileNotFoundException fnfx) {
JOptionPane.showMessageDialog(null, "File could not be found");
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with reading from file");
} catch (ClassNotFoundException cnfx) {
JOptionPane.showMessageDialog(null, "Class could not be found");
} catch (NullPointerException npx) {
System.out.println("blah");
} finally {
try {
ois.close();
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with closing file");
}
}
return cancerList;
}
When I run the program, it gives a NullPointerException at ois.close() as well as an IOException that produces the pop-up "Problem with reading from file".
I have also tried changing how the file itself is structured, replaced the || (delimiters) with a word or even blank space but nothing changes.
Your FileInputStream is throwing an exception (I'm guessing from incorrect file permissions, but you'll have to look into this further); this occurs before you initialize your ObjectInputStream, so ois is still null when you reach your finally block which is resulting in a null pointer exception. It's usually a good idea to precede close statements in final blocks by null pointer checks for this reason.
When using an ObjectInputStream the input data is required to be in a byte format that can be read into a serialized object, Disease in this case. If the format is not in the expected format a StreamCorruptedException will be thrown. If you are changing the text file manually, chances are that this exception is being thrown but the exact message is not displayed as you are displaying a generic Problem with reading from file message.
Displaying the stack trace will help
iox.printStackTrace();
Ensure that you are writing the objects correctly to file. Alternatively you could use a text based file, and use Printwriter to write, Scanner to read. You can use || for as a Scanner delimiter.

write object to file java

I am creating an application that manages an agenda. Each contact must be written in the object file. How can I check if the file exists and is there a way to write the next object without overwriting??
My class:
import java.io.*;
public class WriteFile {
public void setContact(Agenda contact){
ObjectOutputStream out;
try{
File file = new File("Contacts.txt");
out = new ObjectOutputStream(new FileOutputStream(file));
out.writeObject(contact);
out.flush();
out.close();
System.out.println("Object written to file");
}
catch (FileNotFoundException ex) {
System.out.println("Error with specified file") ;
ex.printStackTrace();
}
catch (IOException ex) {
System.out.println("Error with I/O processes") ;
ex.printStackTrace();
}
}
}
Using your code, I believe the easiest thing to do would be to make use of the file.exists() method to check to see if the file exists.
boolean exists = file.exists();
Then you can use the following constructor for the the FileOutputStream:
public FileOutputStream(File file, boolean append) throws FileNotFoundException
to append to the end of the file. Obviously the construction of that object should be wrapped in an if-else clause, depending on the value of the file.exists().
Use file.exists() to check if a file exists.
If it does, read in the old data from the file then write the old data and the new data to a temporary file. Delete the old file and rename the temp file to 'Contacts.txt'.
first, object in which able to be written have to be an instance of a class which implements Serializable interface, that interface has no method to be implemented, it's just a flag which tell that it's instaces are can be serialized.
second to make writing countinously, or not overwrite the old data, use this in your code:
out = new ObjectOutputStream(new FileOutputStream(file), true);
there is a 'true' at the back seat, to make it appends,.

Categories

Resources