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,.
Related
I'm having a problem with an assignment from school. I'm meant to output an arraylist of objects to a file, which I can do. But I'm supposed to check if the file exists, and if it does, then to output to that file, and not create a new one.
I've tried putting the FileOutputStream declaration outside of my if statement, but then the file will always exist.
I've also tried creating a new ObjectOutputStream in my first half of the if statement, but I get an IOException about the headers.
How do I write the objects (of class Employee) to a file that already exists?
public void saveEmployeesToFile() {
try {
File employeeFile = new File("CurrentEmployees.emp");
if (employeeFile.exists()) {
System.out.println("File already exists");
} else {
FileOutputStream employeeFileObject = new FileOutputStream(employeeFile);
ObjectOutputStream output = new ObjectOutputStream(employeeFileObject);
for (Employee thisEmp : getEmployees()) {
output.writeObject(thisEmp);
}
System.out.println("Employees successfully saved to new file");
employeeFileObject.close();
output.close();
}
} catch (IOException ioe) {
System.out.println("Error initializing stream");
System.out.println(ioe.getMessage());
}
}
You can leverage the newer NIO package.
Your question is essentially, "how do I create a FileOuputStream for a file that already exists?"
Path employeeFilePath = Paths.get(employeeFile.toURI());
FileOutputStream employeeFileObject;
if (employeeFile.exists()) {
employeeFileObject = Files.newOutputStream(employeeFilePath, StandardOpenOption.TRUNCATE_EXISTING);
}
else {
employeeFileObject = Files.newOutputStream(employeeFilePath, StandardOpenOption.CREATE_NEW);
}
// Proceed to write data
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.
This is the code I use when I try to read some specific text in a *.txt file:
public void readFromFile(String filename, JTable table) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String a,b,c,d;
for(int i=0; i<3; i++)
{
a = bufferedReader.readLine();
b = bufferedReader.readLine();
c = bufferedReader.readLine();
d = bufferedReader.readLine();
table.setValueAt(a, i, 0);
table.setValueAt(b, i, 1);
table.setValueAt(c, i, 2);
table.setValueAt(d, i, 3);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the reader
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And it is called in this way:
readFromFile("C:/data/datafile.txt", table1)
The problem is the following: the 1st time I open the program the *.txt file I'm going to read does not exist, so I thought I could use the function exists(). I have no idea about what to do, but I tried this:
if(("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1)
}
It is not working because NetBeans gives me a lot of errors. How could I fix this?
String has no method named exists() (and even if it did it would not do what you require), which will be the cause of the errors reported by the IDE.
Create an instance of File and invoke exists() on the File instance:
if (new File("C:/data/datafile.txt").exists())
{
}
Note: This answer use classes that aren't available on a version less than Java 7.
The method exists() for the object String doesn't exist. See the String documentation for more information. If you want to check if a file exist base on a path you should use Path with Files to verify the existence of the file.
Path file = Paths.get("C:/data/datafile.txt");
if(Files.exists(file)){
//your code here
}
Some tutorial about the Path class : Oracle tutorial
And a blog post about How to manipulate files in Java 7
Suggestion for your code:
I'll point to you the tutorial about try-with-resources as it could be useful to you. I also want to bring your attention on Files#readAllLines as it could help you reduce the code for the reading operation. Based on this method you could use a for-each loop to add all the lines of the file on your JTable.
you can use this code to check if the file exist
Using java.io.File
File f = new File(filePathString);
if(f.exists()) { /* do something */ }
You need to give it an actual File object. You're on the right track, but NetBeans (and java, for that matter) has no idea what '("C:/data/datafile.txt")' is.
What you probably wanted to do there was create a java.io.File object using that string as the argument, like so:
File file = new File ("C:/data/datafile.txt");
if (file.exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
Also, you were missing a semicolon at the end of the readFromFile call. Im not sure if that is just a typo, but you'll want to check on that as well.
If you know you're only ever using this File object just to check existence, you could also do:
if (new File("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
If you want to ensure that you can read from the file, it might even be appropriate to use:
if(new File("C:/data/datafile.txt").canRead()){
...
}
as a condition, in order to verify that the file exists and you have sufficient permissions to read from the file.
Link to canRead() javadoc
I serialize an object and save it as a file on my HDD. When I'm reading it, in only some occasions it throws EOFException. After couple of hours debugging I am not able to find a problem.
Here is my code:
public void serialize(MyClass myClass,String path) {
FileOutputStream foStream = null;
ObjectOutputStream ooStream = null;
try {
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
foStream = new FileOutputStream(file);
ooStream = new ObjectOutputStream(foStream);
ooStream.writeObject(myClass);
} catch (Throwable t) {
log.error(t);
} finally {
if (ooStream != null) {
try {
ooStream.flush();
ooStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
}
For getting Object:
public MyClass deSerialize(String path) {
MyClass myClass=null;
FileInputStream fiStream = null;
ObjectInputStream oiStream = null;
String errorMessage = "";
try {
File file = new File(path);
if (!file.exists()) {
return null;
}
fiStream = new FileInputStream(path);
oiStream = new ObjectInputStream(fiStream);
Object o = oiStream.readObject();
myClass = (MyClass) o;
} catch (Throwable t) {
log.warn(t);
} finally {
if (oiStream != null) {
try {
oiStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
return myClass;
}
Stacktrace:
java.io.EOFException at
java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2498)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
at java.util.LinkedList.readObject(LinkedList.java:776) at
sun.reflect.GeneratedMethodAccessor583.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585) at
java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946)
at
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
at
java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
at
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
Question:
My serialized object is now corrupted and then is it rubbish now?
Because this object is responsible for rendering the UI which saved by user. If User logs in it should render previously saved state of UI. However for some user the file cannot be deserialized.
EOFException means you are trying to read past the end of the file. Normally you don't have any way of knowing whethere there are more objects to read, other than trying it, so you shouldn't regard EOFException as a problem in the first place. If it is thrown in a situation where you think you know there are more objects in the file, e.g. when you have prefixed an object count to the file, it indicates a problem with the code that wrote the file, or possible corruption of the file itself. Another example is a zero length file that shouldn't be zero length. Whatever the problem is, it can't be solved by the reading end, it is already too late.
I cannot see any problem with the writing and reading of the file.
So my best guess is that the problem is at the file level. For example:
you could be writing one file and reading a different one, or
you could be reading the file before the file write completes, or
something else could be clobbering the file in between the running of your write code and read code.
I suggest that you add some tracing code that uses File.length() to find out what the file size is after you've written it and before you read it.
A couple of other possibilities:
the writer and reader code is using different versions of MyClass (or a dependent class) with incompatible representations and the same serialVersionId values, or
you could be using custom readObject and writeObject methods that are incompatible.
In my case, EOF Exception was solved by ensuring the read and writes to the file were thread safe. Like Stephen C answered above, if you try to write to a file which you also are trying to read from say from another thread, you may be stepping on the ObjectInputStream which is going to throw EOF Exception in this case.
I have one problem, that is I have one string of data and I want to save it into a separate file every time. Please give me a suggestion.
Thanks,
vara kumar.pjd
Use a timestamp in the filename so you can be sure it is unique. Below example uses a timestamp in milliseconds which should be enough in most cases.
If you expect you can have multiple files within 1 millisecond then you could do something with a GUID/UUID. Note that GUID/UUID could result in duplicates too, however this chance is extremely rare.
import java.io.*;
class FileWrite
{
public static void main(String args[])
{
try{
// Create file
FileWriter fstream = new FileWriter(System.currentTimeMillis() + "out.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write("Hello Java");
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
You don't need to compute the filename by yourself, have a look at File.createTempFile.
From the javadoc:
Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name. If this method returns successfully then it is guaranteed that:
The file denoted by the returned abstract pathname did not exist before this method was invoked, and
Neither this method nor any of its variants will return the same abstract pathname again in the current invocation of the virtual machine.
This method provides only part of a temporary-file facility. To arrange for a file created by this method to be deleted automatically, use the deleteOnExit() method.
A one liner. Using base 36 for the ids will make the file names shorter.
IOUtils.write(text, new FileWriter(Long.toString(System.currentTimeMillis(), 36)+".txt")));
http://commons.apache.org/io/
One solution can be, use a random number generator to generate a random number. Use this random number with some text as a filename. Maintain a list of already used names and each time you are saving the file, check through this list if the file name is unique.
One of possible ways to get File object with unique name could be:
public static File getUniqueFile(String base, String ext, int index) {
File f = new File(String.format("%s-%03d.%s", base, index, ext));
return f.exists() ? getUniqueFile(base, ext, index + 1) : f;
}
Update: and here goes basic usage/test case:
String s = "foo string\n";
FileWriter writer = null;
for (int i = 0; i < 10; i++) {
File f = getUniqueFile("out", "txt", 0);
try {
writer = new FileWriter(f);
writer.write(s);
writer.close();
writer = null;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
if (writer != null) { try { writer.close(); } catch (Exception e) {} }