I'm trying to write a binary file to a specified folder, however it keeps giving me an exception.
For example, if I write the file without specifying any folder the program writes it with no problem:
public void saveFile(String name) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(name + ".bin"));
out.writeObject(this);
out.close();
}
However, when I try to specify the folder the program just doesn't write the file:
public void saveFile(String name) throws IOException {
File location = new File("/path/" + name + ".bin");
FileOutputStream fos = new FileOutputStream(location);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(this);
out.close();
fos.close();
}
I tryed several different ways but still no solution.
Does anybody know what am I doing wrong?
Check if the class which you want to write is Serializable or not.
public class Foo implements java.io.Serializable{
//...
public void write() throws IOException{
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("Test.bin"));
os.writeObject(this);
os.close();
}
}
Another problem:
If there is no folder named path it cannot write the object
Check your code again.
The Only reason seems for non Serialization is that u might not have implemented Serializable interface
and give your path name correctly for eg:-"C:\Users\.."
Hope it works
Related
I'm experimenting with Serialization and wrote the following class:
public static void main(String[] args) throws ClassNotFoundException{
File file = new File("D:/serializable.txt");
try(FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)){
// SerialTest st = new SerialTest();
// ous.writeObject(st);
SerialTest st = (SerialTest) ois.readObject();
System.out.println(st);
} catch (IOException e) {
e.printStackTrace();
}
}
Serialized class:
public static class SerialTest implements Serializable{
private int count;
private Object object;
public int count(){
return count;
}
public Object object(){
return object;
}
private void readObject(ObjectOutputStream ous) throws IOException{
ous.writeObject(object);
ous.writeInt(count);
}
private void writeObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
ois.readInt();
ois.readObject();
}
}
After serializing the object as in the commeted code, I tried to desirialize it as specified here. I got
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
Moroever, the content of the file containing the serialized object is chaged.
But when I remove the resource-declarations
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);
from the try-with-resources clasuse it works completely fine. Why? Why the resource declarations affects the deserialization?
Well without the write calls, you're currently creating an empty file to start with, because that's what the FileOutputStream constructor you're calling does. If the file already exists, it is truncated to be 0 bytes long. So when you then try to read an object from it, there's nothing to read.
Even with the writing part uncommented, there's still the possibility of buffering issues, where the data hasn't actually been written to the file yet.
I would strongly urge you to write the file and close the output stream, and then separately open it for input. Having the same file open for read and write at the same time seems like a recipe for confusing results to me.
So the code would look something like this:
// Exception handling omitted as this is just test code
public static void main(String[] args) throws Exception {
File file = new File("D:/serializable.txt");
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos)) {
SerialTest st = new SerialTest();
ous.writeObject(st);
}
try (FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)) {
SerialTest st = (SerialTest) ois.readObject();
System.out.println(st);
}
}
Leaving aside the fact that you obviously have the content of readObject() and writeObject() back to front:
private void readObject(ObjectOutputStream ous) throws IOException{
ous.writeObject(object);
ous.writeInt(count);
}
Here you are writing first the object then the integer.
private void writeObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
ois.readInt();
ois.readObject();
}
Here you are reading first the integer then the object.
Ain't gonna work.
BUT ... You don't need either of these methods. Remove them. Or, if you want to serialize data of the parent class, fix them to (a) call defaultReadObject() and defaultWriteObject() respectively, and get rid of what you already have in there, which will already happen by default, or at least when you read the object and the integer in the same order as you wrote them, store them into the respective instance members.
NB serialized data isn't text and shouldn't be stored in files named .txt.
I'm struggeling with storing a streamresult .xml file temporarily and use it to create a pdf with xslt.
I have a method (methodCalled) that creates an empty file. It passes that empty file and an object with data to a methode objectToXml in the xmlConverter Class. When I execute, I always get a nullpointer exception on the line with os.close() in the xmlConverter Class. Can you help me to understand why this happens?
It works fine when I pass a String (with a filepath) instead of the file object to new FileOutputStream(file);.
public function methodCalled() {
File file = new File(".");
try {
file.createNewFile();
xmlConverter.objectToXml(file, expense);
}
catch(IOException e) {
e.printStackTrace();
}
}
Class xmlConverter:
public class XmlConverter {
#Autowired
private Marshaller marshaller;
public void objectToXml(File file, Object object) throws IOException {
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
marshaller.marshal(object, new StreamResult(os));
} finally {
os.close();
}
}
}
Thanks for your help guys :)
public class Inventory implements Serializable {
ArrayList<Product> productlist;
File file;
public Inventory(){
productlist = new ArrayList<Product>();
file = new File("build/classes/inventory/inv.ser");
if(!file.exists()){
try {
file.getParentFile().mkdirs();
file.createNewFile();
} catch (IOException ex) {
Logger.getLogger(Inventory.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(file.length() !=0){
loadFile(file);
}
}
public void addProduct(Product product){
productlist.add(product);
saveFile(this.file);
}
public void saveFile(File file){
try{
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(productlist);
out.close();
fos.close();
} catch(FileNotFoundException ex){System.out.println("FileNotFoundException");}
catch(IOException ex){System.out.println("InputException");}
}
public void loadFile(File file){
try{
FileInputStream fis = new FileInputStream(file);
ObjectInputStream in = new ObjectInputStream(fis);
productlist=(ArrayList<Product>)in.readObject();
in.close();
fis.close();
} catch(FileNotFoundException ex){ System.out.println("FileNotFoundException"); }
catch(IOException ex){System.out.println("OutputException");}
catch(ClassNotFoundException ex){System.out.println("ClassNotFoundException");}
}
}
Does writeObject() overwrite the content of the existing file or append the objects to the existing file?
And is it a good idea to serialize an ArrayList of Objects like what i did inside the saveFile method?
Does writeObject() overwrite the content of the existing file or append the objects to the existing file?
Neither. It writes the object to the underlying stream. The underlying stream is a serial byte stream that can only be appended to. In this case the underlying stream is backed by an underlying file, which has or has not already been overwritten, depending on how you constructed the FileOutputStream. It has nothing to do with writeObject(). In any case you can't successfully append to a file of serialized objects without taking special measures.
And is it a good idea to serialize an ArrayList of Objects like what i did inside the saveFile method?
Compared to what?
N.B.
When you get an exception, print it. Not just some message of your own devising.
Creating a file just so you can test it for zero length doesn't make sense.
The directory build/classes/inventory won't be there at runtime once you stop using the IDE. This is no place to put a file.
You could try FileUtils function to write list of object into plane text file.
Please find below URL for reference -
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#writeLines-java.io.File-java.util.Collection-java.lang.String-boolean-
e.g.
FileUtils.writeLines(new File(fileToAttach), list);
I am trying to serialize the following class:
public class Library extends ArrayList<Book> implements Serializable{
public Library(){
check();
}
using the following method of that class:
void save() throws IOException {
String path = System.getProperty("user.home");
File f = new File(path + "\\Documents\\CardCat\\library.ser");
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream (f));
oos.writeObject(this);
oos.close();
}
However, rather than creating a file called library.ser, the program is creating a directory named library.ser with nothing in it. Why is this?
If its helpful, the save() method is initially called from this method (of the same class):
void checkFile() {
String path = System.getProperty("user.home");
File f = new File(path + "\\Documents\\CardCat\\library.ser");
try {
if (f.exists()){
load(f);
}
else if (!f.exists()){
f.mkdirs();
save();
}
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Library.class.getName()).log(Level.SEVERE, null, ex);
}
}
File.mkdirs() creating a directory instead of a file
That's what it's supposed to do. Read the Javadoc. Nothing there about creating a file.
f.mkdirs();
It is this line that creates the directory. It should be
f.getParentFile().mkdirs();
I'm pretty sure that the call to f.mkdirs() is your problem. If the file doesn't already exist (which seems to be your case), the f.mkdirs() call will give you a directory called "library.ser" instead of a File, which is why your "save()" call isn't working - you can't serialize an object to a directory.
I am trying to understand PrintWriter for a small program I'm making, and I cant seem to get java to make the file and then write on it. When I execute the program below it gives me a Filenotfoundexeption error on line 9. It also fails to make the file in the directory that I specified. I am new to this so please try and keep the answers simple. I am using Eclipse.
import java.io.PrintWriter;
import java.io.File;
public class Testing {
public static void main(String[] args) {
File file = new File ("C:/Users/Me/Desktop/directory/file.txt");
PrintWriter printWriter = new PrintWriter ("file.txt");
printWriter.println ("hello");
printWriter.close ();
}
}
If the directory doesn't exist you need to create it. Java won't create it by itself since the File class is just a link to an entity that can also not exist at all.
As you stated the error is that the file cannot be created. If you read the documentation of PrintWriter constructor you can see
FileNotFoundException - If the given string does not denote an existing, writable regular file and a new regular file of that name cannot be created, or if some other error occurs while opening or creating the file
You should try creating a path for the folder it contains before:
File file = new File("C:/Users/Me/Desktop/directory/file.txt");
file.getParentFile().mkdirs();
PrintWriter printWriter = new PrintWriter(file);
import java.io.PrintWriter;
import java.io.File;
public class Testing {
public static void main(String[] args) throws IOException {
File file = new File ("C:/Users/Me/Desktop/directory/file.txt");
PrintWriter printWriter = new PrintWriter ("file.txt");
printWriter.println ("hello");
printWriter.close ();
}
}
throw an exception for the file.
Pass the File object to the constructor PrintWriter(File file):
PrintWriter printWriter = new PrintWriter(file);
import java.io.File;
import java.io.PrintWriter;
public class Testing
{
public static void main(String[] args)
{
File file = new File("C:/Users/Me/Desktop/directory/file.txt");
PrintWriter printWriter = null;
try
{
printWriter = new PrintWriter(file);
printWriter.println("hello");
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
if ( printWriter != null )
{
printWriter.close();
}
}
}
}
You should have a clear idea of exceptions in java.
In java there are checked exceptions and unchecked exceptions.
Checked exceptions are checked (not thrown,just checked) by the compiler at Compile time for the smooth execution of the program at run time.
NOTE: And in our program if their is a chance that a checked exception will rise, then we should handle that checked exception either by try catch or by throws key word.Otherwise we will get a compile time Error:
CE:Unexpected Exception java.io.FileNotFoundException;must be caught or declared to be thrown.
How to resolve:
1.Put your code in try catch block:
2.use throws keyword as shown by other guys above.
Advice:Read more about Exceptions.(I personally love this topic)
Java doesn't normally accept "/" to use in defining a file directory, so try this:
File file = new File ("C:\\Users\\user\\workspace\\FileTester\\myFile.txt");
If the file doesn't exist do:
try {
file.createNewFile();
}
catch (IOException e) {
e.printStackTrace();
}
Well I think firstly keep whole main into try catch(or you can use as public static void main(String arg[]) throws IOException ) and then also use full path of file in which you are writing as
PrintWriter printWriter = new PrintWriter ("C:/Users/Me/Desktop/directory/file.txt");
all those directies like users,Me,Desktop,directory should be user made. java wont make directories own its own.
it should be as
import java.io.*;
public class PrintWriterClass {
public static void main(String arg[]) throws IOException{
PrintWriter pw = new PrintWriter("C:/Users/Me/Desktop/directory/file.txt");
pw.println("hiiiiiii");
pw.close();
}
}
import java.io.*;
public class test{
public static void main(Strings []args){
PrintWriter pw = new PrintWriter(new file("C:/Users/Me/Desktop/directory/file.txt"));
pw.println("hello");
pw.close
}
}
The PrintWriter class can actually create the file for you.
This example works in JDK 1.7+.
// This will create the file.txt in your working directory.
PrintWriter printWriter = null;
try {
printWriter = new PrintWriter("file.txt", "UTF-8");
// The second parameter determines the encoding. It can be
// any valid encoding, but I used UTF-8 as an example.
} catch (FileNotFoundException | UnsupportedEncodingException error) {
error.printStackTrace();
}
printWriter.println("Write whatever you like in your file.txt");
// Make sure to close the printWriter object otherwise nothing
// will be written to your file.txt and it will be blank.
printWriter.close();
For a list of valid encodings, see the documentation.
Alternatively, you can just pass the file path to the PrintWriter class without declaring the encoding.
Double click the file.txt, then save it, command + s, that worked in my case. Also, make sure the file.txt is saved in the project folder.
If that does not work.
PrintWriter pw = new PrintWriter(new File("file.txt"));
pw.println("hello world"); // to test if it works.
If you want to use PrintWrite then try this code
public class PrintWriter {
public static void main(String[] args) throws IOException {
java.io.PrintWriter pw=new java.io.PrintWriter("file.txt");
pw.println("hello world");
pw.flush();
pw.close();
}
}