EOFException while reading with objectInputStream [duplicate] - java

This question already has answers here:
EOFException when reading files with ObjectInputStream [duplicate]
(5 answers)
Closed 5 years ago.
I want write object to file and read them, but I'm getting error. Line 51 in Main.java is while loop which should display objects.
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at com.sdajava.rwobj.Main.main(Main.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
My code: write object first and read them. The data is write to a file.
String fileName = "c://Users//lukas//obj.txt";
Person p1 = new Person("Jan", "Kowalski", 21);
Person p2 = new Person("Jan", "Kowalski", 21);
OutputStream fileOutputStream = null;
ObjectOutput objectOutputStream = null;
OutputStream bufferOut = null;
try {
fileOutputStream = new FileOutputStream(fileName);
bufferOut = new BufferedOutputStream(fileOutputStream);
objectOutputStream = new ObjectOutputStream(bufferOut);
objectOutputStream.writeObject(p1);
objectOutputStream.writeObject(p2);
objectOutputStream.close();
} finally {
if (objectOutputStream != null) {
objectOutputStream.close();
}
fileOutputStream.close();
bufferOut.close();
objectOutputStream.close();
}
try {
FileInputStream fileInputStream = new FileInputStream(fileName);
InputStream bufferIn = new BufferedInputStream(fileInputStream);
ObjectInputStream objectInputStream
= new ObjectInputStream(bufferIn);
Person readCase = null;
List<Person> recordList = new ArrayList<>();
do {
readCase = (Person) objectInputStream.readObject();
if (readCase != null) {
recordList.add(readCase);
}
} while (readCase != null);
fileOutputStream.close();
objectOutputStream.close();
} catch (FileNotFoundException err){
err.printStackTrace();
}
What is wrong?

do {
readCase = (Person) objectInputStream.readObject();
if (readCase != null) {
recordList.add(readCase);
}
} while (readCase != null);
This loop is not correct. readObject() does not return null at end of stream. It can do that any time you wrote a null. At end of stream it throws EOFException. So:
for (;;) {
try {
readCase = (Person) objectInputStream.readObject();
recordList.add(readCase);
}
catch (EOFException exc) {
break;
}
}

As pointed out in the comments you are trying to read more objects then stored, Also if in case you don't know already the number of objects stored, you can try it this way:
try{
while(true)
recordList.add((Person) objectInputStream.readObject());
}
catch(EOFException ex){
//All objects are read when control is here
}

Related

A java program that creates WAV files [duplicate]

With Java:
I have a byte[] that represents a file.
How do I write this to a file (ie. C:\myfile.pdf)
I know it's done with InputStream, but I can't seem to work it out.
Use Apache Commons IO
FileUtils.writeByteArrayToFile(new File("pathname"), myByteArray)
Or, if you insist on making work for yourself...
try (FileOutputStream fos = new FileOutputStream("pathname")) {
fos.write(myByteArray);
//fos.close(); There is no more need for this line since you had created the instance of "fos" inside the try. And this will automatically close the OutputStream
}
Without any libraries:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(bytes);
}
With Google Guava:
Files.write(bytes, new File(path));
With Apache Commons:
FileUtils.writeByteArrayToFile(new File(path), bytes);
All of these strategies require that you catch an IOException at some point too.
Another solution using java.nio.file:
byte[] bytes = ...;
Path path = Paths.get("C:\\myfile.pdf");
Files.write(path, bytes);
Also since Java 7, one line with java.nio.file.Files:
Files.write(new File(filePath).toPath(), data);
Where data is your byte[] and filePath is a String. You can also add multiple file open options with the StandardOpenOptions class. Add throws or surround with try/catch.
From Java 7 onward you can use the try-with-resources statement to avoid leaking resources and make your code easier to read. More on that here.
To write your byteArray to a file you would do:
try (FileOutputStream fos = new FileOutputStream("fullPathToFile")) {
fos.write(byteArray);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Try an OutputStream or more specifically FileOutputStream
Basic example:
String fileName = "file.test";
BufferedOutputStream bs = null;
try {
FileOutputStream fs = new FileOutputStream(new File(fileName));
bs = new BufferedOutputStream(fs);
bs.write(byte_array);
bs.close();
bs = null;
} catch (Exception e) {
e.printStackTrace()
}
if (bs != null) try { bs.close(); } catch (Exception e) {}
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
////////////////////////// 1] File to Byte [] ///////////////////
Path path = Paths.get(p);
byte[] data = null;
try {
data = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(Agent1.class.getName()).log(Level.SEVERE, null, ex);
}
/////////////////////// 2] Byte [] to File ///////////////////////////
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
I know it's done with InputStream
Actually, you'd be writing to a file output...
This is a program where we are reading and printing array of bytes offset and length using String Builder and Writing the array of bytes offset length to the new file.
`Enter code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//*This is a program where we are reading and printing array of bytes offset and length using StringBuilder and Writing the array of bytes offset length to the new file*//
public class ReadandWriteAByte {
public void readandWriteBytesToFile(){
File file = new File("count.char"); //(abcdefghijk)
File bfile = new File("bytefile.txt");//(New File)
byte[] b;
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream (file);
fos = new FileOutputStream (bfile);
b = new byte [1024];
int i;
StringBuilder sb = new StringBuilder();
while ((i = fis.read(b))!=-1){
sb.append(new String(b,5,5));
fos.write(b, 2, 5);
}
System.out.println(sb.toString());
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis != null);
fis.close(); //This helps to close the stream
}catch (IOException e){
e.printStackTrace();
}
}
}
public static void main (String args[]){
ReadandWriteAByte rb = new ReadandWriteAByte();
rb.readandWriteBytesToFile();
}
}
O/P in console : fghij
O/P in new file :cdefg
You can try Cactoos:
new LengthOf(new TeeInput(array, new File("a.txt"))).value();
More details: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html

How to get an already existing file (on my computer) in my method and convert it to InputStream? [duplicate]

This question already has answers here:
Load a file from external storage to Inputstream
(4 answers)
Closed 3 years ago.
I've a generated file in D:/EXPORT_BASE/Export_report. What I need to do is use the filePath string to fetch this file from my local, and then convert this to InputStream.
String filePath = D:/EXPORT_BASE/Export_report/1557834965979_report.txt
I need to use the String to get the file and write it to InputStream.
Basically, like this:
public InputStream getInputStreamFromFilepath(String filepath) throws FileNotFoundException {
File fileToOpen = new File(filepath);
return new FileInputStream(fileToOpen);
}
File file = new File("C:/myTest.txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
System.out.println("Total file size to read (in bytes) : "
+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}

Iterating with ObjectInputStream.readObject() from a .txt-file

I am having trouble reading object-data from a .txt-file using the readObject()-method from ObjectInputStream.
I am writing multiple User-objects to a .txt to save users when the server for the program is down, and the writing works fine, though when I am trying to read the information back, I don't know how to loop through/read the next line in the file.
public void readObjectFromFile() {
boolean cont = true;
User user;
try {
FileInputStream fileIn = new FileInputStream("files/userlist.txt");
ObjectInputStream objectIn = new ObjectInputStream(fileIn);
while(cont){
Object obj = objectIn.readObject();
if(obj != null) {
registeredUsers.add((User)objectIn.readObject());
user = (User)obj;
userPasswords.put(user.getUsername(), user.getPassword());
System.out.println(user.getUsername());
}else {
cont = false;
}
}
}catch (Exception ex) {
ex.printStackTrace();
}
}
public void addUserToDatabase(User user) {
try(FileOutputStream fos = new FileOutputStream("files/userlist.txt", true);
ObjectOutputStream oos = new ObjectOutputStream(fos)){
oos.writeObject(user);
oos.write('\n');
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I would want to read the file line-by-line, and store the information of every line in a User-object and store it in the registeredUsers-list.
Okay I solved it!
public void readUsersFromFile() {
try {
FileInputStream fileIn = new FileInputStream("files/userlist.dat");
ObjectInputStream objectIn = new ObjectInputStream(fileIn);
boolean keepReading = true;
try {
while(keepReading) {
User user = (User)objectIn.readObject();
registeredUsers.add(user);
userPasswords.put(user.getUsername(), user.getPassword());
System.out.println(user.getUsername());
objectIn = new ObjectInputStream(fileIn);
}
}catch(EOFException e) {
keepReading = false;
}
}catch (Exception ex) {
ex.printStackTrace();
}
}
Problem: You are reading twice in while loop.
First Call:
objectIn.readObject()
Second Call:
registeredUsers.add((User)objectIn.readObject());
Solution:
Do not call readObject() method twice use the reference that is already been taken.
Other then functional problem, you can also correct the following things to make your code better:
Don't make while loop so complex.
No need to use separate boolean counter in while loop.
Just typecast once to user not multiple times (at the time of readObject() call itself).
Please refer following code:
User user = null;
while((user = (User) objectIn.readObject()) != null){
registeredUsers.add(user);
userPasswords.put(user.getUsername(), user.getPassword());
System.out.println(user.getUsername());
}
Are you already getting the data from the file?
I have done this before with pipe-delimited files ("|"), so:
value1|value2|value3
Not sure of the makeup of your file, but if you are already reading the data then you can skip to next lines & make new User objects like so:
private List <UserEntry> collectFileContents(InputStream is, String fileName) throws Exception {
try {
List <UserEntry> userEntries = new ArrayList <UserEntry>();
String line = "";
BufferedReader br = new BufferedReader(new InputStreamReader(is));
br.readLine();
while ((line = br.readLine()) != null) {
if (line.length() > 0) {
UserEntry entry = new UserEntry();
try {
String[] lineValues = line.split("\\|",-1);
entry.setVal1(lineValues[0]);
entry.setVal2(lineValues[1]);
//etc..
userEntries.add(entry);
} catch (ArrayIndexOutOfBoundsException ex) {
//error handling here
continue;
}
}
}
return userEntries;
}catch(Exception ex) {
//error handling here
}
}
This should create a list of Users, and I save them to the DB in a different method. But you can do it however you like. Also of note - in my file I have a title line as the first line. So this code will skip the first line. Again, not sure about how your file is set up.

NullPointerException when reading a file

When I load this file, I always get the NullPointerException. I try many thing and I could not find a way to fix it. When I saved I used the Game object.
#Override
public void load(Superhero aHero,Villain aVillain) throws IOException, ClassNotFoundException {
ObjectInputStream ois = null;
FileInputStream fis = null;
File f = new File("C:\\prog24178\\dcgames.dat");
Game aGame = new Game(aHero,aVillain);
try {
fis = new FileInputStream(f);
ois = new ObjectInputStream(fis);
while(true){
aGame = (Game) ois.readObject();
System.out.println(aGame);
}
} catch(EOFException eof){
ois.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(DcGameController.class.getName()).log(Level.SEVERE, null, ex);
}
}
When I open the file I see something like that:
’ sr
model.Game ^r Z gameOverZ heroTurnL theHerot Lmodel/Superhero;L
theVillaint Lmodel/Villain;xp sr model.hero.Batman ^r Z armedL sidekickq ~ xr model.Superhero ^r I energyZ secretIdentityL codenamet Ljava/lang/String;L hometownq ~ xr model.Avatar ^r
I agilityI enduranceI fightingI hitPointsI intuitionI psycheI reasonI strengthL firstNameq ~ L lastNameq ~ xp W t q ~ t Batmant Gotham Citysq ~ t Dickt Grayson ppsr model.villain.Cheetah ^r xr
model.Villain ^r I energyZ insaneL codenameq ~ xq ~ b t Priscillat Rich t Cheetah
So I know it's working but I would like to read and after that I could set the setting I need to use.
That's my save method :
#Override
public void saveGame(Game aGame) {
File aSaveFile = new File("C:\\prog24178\\dcgames.dat");
FileOutputStream fos = null;
if (!aSaveFile.getParentFile().exists()) {
aSaveFile.getParentFile().mkdir();
}
try {
if (!aSaveFile.exists()) {
aSaveFile.createNewFile();
}
if (aSaveFile.length() > 0) {
fos = new FileOutputStream(aSaveFile, true);
} else {
fos = new FileOutputStream(aSaveFile, false);
}
if (oos == null) {
oos = new ObjectOutputStream(fos);
}
oos.writeObject(aGame);
} catch (FileNotFoundException ex) {
} catch (Exception x) {
System.out.println("Something bad happened" + x);
}
}
Thanks for helping me to fix my issue.
I think there 2 problems u should check,
1.fos = new FileOutputStream(aSaveFile, true);
if aSaveFile already has some data and u append another object data to aSaveFile, its data will be confused, u'll not be able to bring the object back.
2.oos.writeObject(aGame);
when u finish writeObject(), u should flush the stream buffer using oos.flush();

Deserialize an ArrayList?

I am trying to add serilization and deserialization to my app. I have already added serization which makes it into a textfileThis problem is involving ArrayLists. I was browsing this page: http://www.vogella.com/articles/JavaSerialization/article.html when I saw this code:
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
p = (Person) in.readObject();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(p);
}
I was confused on this line:
p = (Person) in.readObject();
How do I make this line an ArrayList when creating an ArrayList is not as simple as that:
List<String> List = new ArrayList<String>();
Thanks for the help in advance!
I took the code directly from the website that you provided a link for and modified it for an ArrayList. You mention "How do I make this line an ArrayList when creating an ArrayList is not as simple as that", I say creating an ArrayList is as simple as that.
public static void main(String[] args) {
String filename = "c:\\time.ser";
ArrayList<String> p = new ArrayList<String>();
p.add("String1");
p.add("String2");
// Save the object to file
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(p);
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
// Read the object from file
// Save the object to file
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
p = (ArrayList<String>) in.readObject();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(p);
}
prints out [String1, String2]
Have you written a whole ArrayList as an object in the file?
Or have you written Persons object that were in an ArrayList in a loop in the file?

Categories