I need to save an arraylist of hashmaps to an external file. I can use any format expect for a text file, because the program is set to ignore text files (specially, anything with a .txt extension). The hashmaps are pretty straightforward, just words with counts of those words. What is the ideal file format to store this in?
You could use java.util.Properties.
Properties properties = new Properties();
properties.putAll(yourMap); // You could also just use Properties in first place.
try (OutputStream output = new FileOutputStream("/foo.properties")) {
properties.store(output, null);
}
You can read it later by
Properties properties = new Properties();
try (InputStream input = new FileInputStream("/foo.properties")) {
properties.load(input);
}
// ... (Properties implements Map, you could just treat it like a Map)
See also:
Java Tutorials - Essential Classes - Properties
You could use serialization:
ObjectOutputStream stream = null;
try
{
File f = new File(filename);
stream = new ObjectOutputStream(new FileOutputStream(f));
stream.writeObject(your_arraylist);
}
catch (IOException e)
{
// Handle error
}
finally
{
if (stream != null)
{
try
{
stream.close();
}
catch (Exception e) {}
}
}
And read it in using:
ObjectInputStream stream = null;
try
{
stream = new ObjectInputStream(new FileInputStream(f));
your_arrayList = (your_arrayList type here)stream.readObject();
}
catch (Throwable t)
{
// Handle error
}
finally
{
if (stream != null)
{
try
{
stream.close();
}
catch (Exception e) {}
}
}
Related
I'm working on appending objects to a binary file. My file is:
File f=new File("person.dat");
I'm getting an error (java.io.StreamCorruptedException: invalid stream header: 79737200) when I attempt to open the binary file. As far as I can tell the program writes the data just fine, but as soon as I try reading from it, I get the above error. Any help is appreciated!
My Code to write:
AppendObjectOutputStream out = null;
try {
out = new AppendObjectOutputStream(new FileOutputStream(f, true));
out.writeObject(new Student(name, age));
out.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
out.close();
}
My class for making appendable:
public class AppendObjectOutputStream extends ObjectOutputStream {
public AppendObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {
reset();
}
}
My partial code for reading and adding objects to an ArrayList:
Course course = new Course();
Student st = null;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new FileInputStream("person.dat"));
try
{
while (true)
{
st = (Student) in.readObject();
course.addAccount(st); //adds student object to an ArrayList in
//class Course
}
}
catch (EOFException ex) {
}
}
catch (Exception ex) {
ex.printStackTrace();
} finally {
in.close();
}
UPDATE:
Current code to read but its not printing anything to screen:
try(ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(Files.newInputStream(f))))
{
while (ois.available() > 0)
{
st = (Student) ois.readObject();
studentlist.addAccount(st);
System.out.println(st.getStudentNumber());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
This is how I write to file:
Path f = Paths.get("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(Files.newOutputStream(f, StandardOpenOption.APPEND))))
{
oos.writeObject(new Student(name,age));
}
catch(Exception ex)
{
ex.printStackTrace();
}
Rather than trying to fix your utility classes, I suggest to use the standard classes of the NIO.2 File API.
Try something like (untested):
Path personDataFilePath = Paths.get("person.dat");
// or Java 11:
// Path personDataFilePath = Path.of("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(Files.newOutputStream(personDataFilePath, StandardOpenOption.APPEND)))){
oos.writeObject(new Student(name,age));
} catch (IOException ex) {
// do some error handling here
}
and to read the file, something like (untested):
List<Student> students = new ArrayList<>();
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(personDataFilePath)))){
while (ois.available() > 0){
students.add((Student) ois.readObject());
}
} catch (IOException ex) {
// do some error handling here
}
I have modified the code to work around making a file "appendable". I write a single arraylist object to the file (the arraylist holds a list of student objects). When I want to add a student, I read the object (arraylist) from the file, add my new student to the arraylist and write the arraylist back to the file. It is now working and my file does not have an append format.
Main problem is that I get null result from my zipEntry. What I am doing is getting BLOB.zip from database, directing it to input stream, from there to zipArchiveInputStream and to ZipEntry which returns null every time. I decided to use ZipArchiveInputStream after using ZipInputStream with same null results.
public byte[] getXMLStream() {
try {
return this.jdbcTemplate.queryForObject("SELECT SAVEDATA FROM JDBEVPP1.TEVP005 WHERE GFNR = 357420", byte[].class); }
catch(DataAccessException ex) {
ex.printStackTrace();
return null;}}
#Override
public void getXMLdata() {
byte[] str = getXMLStream();
InputStream myInputStream = new ByteArrayInputStream(str);
ZipArchiveInputStream fis = new ZipArchiveInputStream(myInputStream);
ZipEntry entry = null;
try {
while ( (entry = fis.getNextZipEntry()) != null ) {
System.out.println(entry.getName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
I just need to get this xml and print it in console for testing. Any idea what is wrong here or how to make it work?
EDIT: Inside BLOB is XML format which I need to present on console.
I solve this problem by using GZIPInputStream. It seems it is generic xml at the end..
try {
GZIPInputStream gzip = new GZIPInputStream(bys);
Reader decoder = new InputStreamReader(gzip, "UTF-8");
BufferedReader buffered = new BufferedReader(decoder);
System.out.println(buffered.readLine());
String data = buffered.readLine();
InputSource xml = new InputSource(new StringReader(data));
System.out.println(xml);
} catch (IOException e) {
e.printStackTrace();
}
I want to write to a file from a Map object. Here is my attempt.
try {
stuMap.put(student.getId(), student);
Path file = Paths.get("student.txt"); // to create the file
Files.write(file, stuMap, Charset.forName("UTF-8")); // try to save in the file
/* fileReaderWriter.createFileIn_NIO(stuMap);*/
try {
fileReaderWriter.createFileIn_NIO(stuMap);
} catch (IOException ex) {
System.out.println("file not saved");
}
return true;
} catch (Exception ex) {
System.out.println("not stored in Map");
return false;
}
How do I make this work?
You can use tools like Jackson to write java maps out as json and read it in as map. As others have mentioned, this is only one possible way.
Full working Read/Write Example
#Test
public void loadMapFromFileAndSaveIt(){
Map<Object, Object> map = loadMap("map.json");
map.put("8", "8th");
map.remove("7");
save(map,"/path/to/map2.txt");
}
private Map<Object, Object> loadMap(String string) {
ObjectMapper mapper = new ObjectMapper();
try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("map.json")) {
return mapper.readValue(in, HashMap.class);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
private void save(Map<Object, Object> map,String path) {
try (PrintWriter out = new PrintWriter(path)) {
out.println(toString(map));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String toString(Object obj) {
try (StringWriter w = new StringWriter();) {
new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writeValue(w, obj);
return w.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
If the file map.json on your classpath contains
{
"1":"1th",
"2":"2th",
"3":"3th",
"4":"4th",
"5":"5th",
"6":"6th",
"7":"7th"
}
The code above will modify it and write it to a file /path/to/map2.txt that will contain
{
"1" : "1th",
"2" : "2th",
"3" : "3th",
"4" : "4th",
"5" : "5th",
"6" : "6th",
"8" : "8th"
}
There is concept in java for saving state of object and retrieve it back later called 'Serialization'.
To Write Object
File fileToSaveObject=new File("path");
Object objectToSave=new Object();
FileOutputStream fileOut = new FileOutputStream(fileToSaveObject);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(objectToSave); // It will save 'objectToSave' in given file
out.close();
fileOut.close();
To Read Object
File fileToReadObject=new File("path");
Object objectToRead;
FileInputStream fileIn = new FileInputStream(fileToReadObject);
ObjectInputStream in = new ObjectInputStream(fileIn);
objectToRead= (Object) in.readObject(); // It will return you the saved object
in.close();
fileIn.close();
Just use org.apache.commons.io.FileUtils
import org.apache.commons.io.FileUtils;
yourMap.forEach((key, value) -> {
FileUtils.writeStringToFile(
outputFile, key + ", " + value + "\n", true);
});
A simple variant to solve the problem is to use Gson library:
String str = new Gson().toJson(yourMap);
File file = new File(fileName);
try(FileOutputStream stream = new FileOutputStream(file)) {
file.createNewFile();
stream.write(str.getBytes());
}catch (IOException e){
System.out.println("can't write to file");
}
I am trying to create a new .ser file to store objects if there is not one already present. When this is ran, it throws an EOFException. What exactly is an EOFException and is this method correctly written to create and read a .ser file? Thanks for any feedback.
public void readDatabase() throws IOException {
File dataFile = new File("database.ser");
// If data file does not exist, create it.
if (!dataFile.exists()) {
System.out.println("database.ser does not exist, creating one now . . .");
// if the file doesn't exists, create it
dataFile.createNewFile();
return; // No need to try to read anything from an empty file, so return.
}
ObjectInputStream objectinputstream = null;
boolean cont = true;
try {
FileInputStream streamIn = new FileInputStream(dataFile);
objectinputstream = new ObjectInputStream(streamIn);
while (cont) {
Item obj = null;
try {
obj = (Item) objectinputstream.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (obj != null)
itemList.add(obj);
else
cont = false;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (objectinputstream != null) {
objectinputstream.close();
}
}
}
EOFException:
java.io.EOFException
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2758)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3253)
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:866)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:343)
at hardwarestore.HardwareStore.readDatabase(HardwareStore.java:254)
at hardwarestore.HardwareStore.<init>(HardwareStore.java:33)
at hardwarestore.MainApp.<init>(MainApp.java:24)
at hardwarestore.MainApp.main(MainApp.java:259)
EOFException stands for:
End of File Exception
This typically occurs when you try to read data from a file where the FileReader has reached the end of the file. In other words, no more data to read.
You should catch the exception and close your stream. as it indicates that you have read all the objects in the file. Referring to the answer in this question:
while (true) {
try {
// Read the next object from the stream. If there is none, the
// EOFException will be thrown.
Item obj = (Item) objectinputstream.readObject();
itemList.add(obj);
} catch (EOFException e) {
// If there are no more objects to read, return what we have.
return contactMap;
} finally {
// Close the stream.
in.close();
}
}
I have the following code to write in three files. I have printed the Strings before writing to ensure they have some data in them, the printed Strings show the data given to them by calling this function but on creation of file the files are empty.
Please suggest something.
public static void save(String editedFileText,String srcFileText,String translFileText)throws IOException {
JFileChooser chooser = new JFileChooser();
System.out.println(editedFileText);
System.out.println(srcFileText);
System.out.println(translFileText);
int retrival = chooser.showSaveDialog(null);
if (retrival == JFileChooser.APPROVE_OPTION) {
try {
FileWriter edit = new FileWriter(chooser.getSelectedFile()+".txt");
edit.write(editedFileText.toString());
FileWriter srcFile = new FileWriter(chooser.getSelectedFile()+"_srcText"+".txt");
srcFile.write(srcFileText.toString());
FileWriter trans = new FileWriter(chooser.getSelectedFile()+"_translFile"+".txt");
trans.write(translFileText.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
Get in the habit of creating all Writers, Readers, InputStreams and OutputStreams in try-with-resources statements. It ensures they will be properly closed:
try (FileWriter edit = new FileWriter(chooser.getSelectedFile()+".txt")) {
edit.write(editedFileText);
}
try (FileWriter srcFile = new FileWriter(chooser.getSelectedFile()+"_srcText"+".txt")) {
srcFile.write(srcFileText);
}
try (FileWriter trans = new FileWriter(chooser.getSelectedFile()+"_translFile"+".txt")) {
trans.write(translFileText);
}
If you're just writing a single String, you have the option of using Files.write, which allows you to forego the use of a Writer altogether:
Files.write(Paths.get(chooser.getSelectedFile()+".txt"),
editedFileText.getBytes());
Files.write(Paths.get(chooser.getSelectedFile()+"_srcText"+".txt"),
srcFileText.getBytes());
Files.write(Paths.get(chooser.getSelectedFile()+"_translFile"+".txt"),
translFileText.getBytes());
Add a finally to close the opened files, but first you need to declare them outside the try catch finally:
FileWriter edit,srcFile, trans;
edit = srcFile = trans = null;
try {
edit = new FileWriter(chooser.getSelectedFile()+".txt");
edit.write(editedFileText.toString());
srcFile = new FileWriter(chooser.getSelectedFile()+"_srcText"+".txt");
srcFile.write(srcFileText.toString());
trans = new FileWriter(chooser.getSelectedFile()+"_translFile"+".txt");
trans.write(translFileText.toString());
} catch (Exception ex) {
ex.printStackTrace();
}finally{
if(edit != null)
edit.close();
if(srcFile != null)
srcFile.close();
if(trans != null)
trans.close();
}
FileWriter writer=null;
try {
writer = new FileWriter(filename);
writer.write(sb.toString());
} catch (Exception e) {
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}