Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to save an array of objects to a file and then to be able to read the objects from that file and add them to an Array. I'm not getting any errors, but it doesn't seem to do anything. I'm not sure if my problem lies in my read or write methods.
Movie allmovies = new Movie[4]
public void writeFile()
{
try
{
FileOutputStream fos = new FileOutputStream("movies.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(allmovies);
oos.close();
System.out.println("File Saved");
}
catch(Exception e) {
System.out.println("Error in output:" + e.toString());
}
}
public void readFile()
{
try
{
FileInputStream fis = new FileInputStream("movies.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Movie[] allmovies = (Movie[]) ois.readObject();
ois.close();
System.out.println("File Imported");
}
catch(Exception e)
{
System.out.println("Error in output:" + e.toString());
}
}
Edit: Also the format of the example file we have been given that we need to read is
Movie Title:
Director:
fileSize:
duration:
I was able to get it to write 1 object and read 1 object but it was in a different format when I view the saved file. Is there anyway to get it in the same format as the example?
Also the format of the example file we have been given that we need to
read is
Movie Title:
Director:
fileSize:
duration:
I was able to get it to write 1 object and read 1 object but it was in
a different format when I view the saved file.
Java serialization allows to encode an object to bytes and not to a textual human understandable representation of the serialized object.
If you want really to write the file in the format you show, you should use :
to write the movies in a textual representation : a BufferedWriter wrapping a FileWriter.
For example : new BufferedWriter(new FileWriter("myFile")).
It has an append(CharSequence) method to append String objects and a newLine() method to append a newline.
to read the movies in a textual representation : A BufferedReader wrapping a FileReader.
For example : new BufferedReader(new FileReader("myFile")).
It has a readLine() method to read a line of the stream.
If you want to serialize movies as bytes and only render them as a textual representation, keep the use of the Java serialization and add a processing to display the Movie array in the required textual format.
After deserializing the array, you just need to iterate on it to generate the required textual representation of the movie.
For example to render the read objects in the standard output, you could write :
Movie[] movies = (Movie[]) ois.readObject();
for (Movie movie : movies){
System.out.println("Movie Title:" + movie.getTitle());
System.out.println("Director:" + movie.getDirector());
System.out.println("fileSize:" + String.valueOf(movie.getTitle()));
System.out.println("duration:" + movie.getTitle());
}
This has been done using arrays without any collections. I modified your code a bit, hope this helps.You can directly copy this code and run. It will successfully read the objects and display all four of them. In a future version which I will upload I will add more commenting to increase the clarity for the same.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test {
Movie[] allMovies = new Movie[4];
public static void main(String[] args) {
Test t = new Test();
t.allMovies[0] = new Movie("A","B",1L,2L);
t.allMovies[1] = new Movie("C","D",1L,2L);
t.allMovies[2] = new Movie("E","F",1L,2L);
t.allMovies[3] = new Movie("G","H",1L,2L);
t.writeFile();
t.readFile();
}
public void writeFile()
{
try
{
FileOutputStream fos = new FileOutputStream("movies.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(allMovies);
oos.close();
System.out.println("File Saved");
}
catch(Exception e) {
System.out.println("Error in output:" + e.toString());
}
}
public void readFile()
{
try
{
FileInputStream fis = new FileInputStream("movies.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Movie[] allmovies = (Movie[]) ois.readObject();
for(int i = 0; i < 4; i++){
System.out.println("Movie = " + allmovies[i].movieTitle + " Director = " + allmovies[i].director + " FileSize = " + allmovies[i].fileSize + " Duration = " + allmovies[i].duration);
}
ois.close();
System.out.println("File Imported");
}
catch(Exception e)
{
System.out.println("Error in output:" + e.toString());
}
}
}
class Movie implements Serializable{
private static final long serialVersionUID = 1647631086810497694L;
String movieTitle;
String director;
Long fileSize;
Long duration;
Movie(String m, String d, Long fs, Long dur){
this.movieTitle = m;
this.director = d;
this.fileSize = fs;
this.duration = dur;
}
}
Related
I want to load the flat text file passed in as 'TMFlatFile' (which is the .tsv file format to use in MALLET) into into the fileReader variable.
I have created the method, RunTopicModelling() and am having a problem with the try/except block.
I have created my File and FileInputStream objects, but dont know how to load it correctly into fileReader?
I have an error that "The method read(CharBuffer) in the type InputStreamReader is not applicable for the arguments (int)".
public class TopicModelling {
private void StartTopicModellingProcess(String filePath) {
JSONIOHelper jsonIO = new JSONIOHelper();
jsonIO.LoadJSON(filePath);
ConcurrentHashMap<String, String> lemmas = jsonIO.GetDocumentsFromJSONStructure();
SaveLemmaDataToFile("topicdata.txt" ,lemmas);
}
private void SaveLemmaDataToFile(String TMFlatFile, ConcurrentHashMap<String, String> lemmas) {
for (Entry<String, String> entry : lemmas.entrySet()) {
try (FileWriter writer = new FileWriter(TMFlatFile)) {
;
writer.write(entry.getKey() + "\ten\t" + entry.getValue() + "\r\n");
} catch (Exception e)
{
System.out.println("Saving to flat text file failed...");
}
}
}
private void RunTopicModelling(String TMFlatFile, int numTopics, int numThreads, int numIterations) {
ArrayList<Pipe> pipeList = new ArrayList <Pipe>();
// Pipes: tokenise, map to features
pipeList.add(new CharSequence2TokenSequence (Pattern.compile("\\p{L}[\\p{L}\\p{P}]+\\p{L}")));
pipeList.add(new TokenSequence2FeatureSequence());
InstanceList instances = new InstanceList (new SerialPipes(pipeList));
InputStreamReader fileReader = null;
//loads the file passed in via the TMFlatFile variable into the fileReader variable - this block I have a problem with
try {
File inFile = new File(TMFlatFile);
FileInputStream fis = new FileInputStream(inFile);
int line;
while ((line = fis.read()) != -1) {
}
fileReader.read(line);
}
fis.close();
}catch(
Exception e)
{
System.out.println("File Load Failed");
System.exit(1);
}
\\ // linking data to the pipeline
instances.addThruPipe(new CsvIterator(fileReader,Pattern.compile("^(\\S*)[\\s,]*(\\S*)[\\s,]*(.*)$"),3,2,1));
}
Can someone tell me what is the correct way to do this?
It's hard to say what the immediate issue is because the code sample provided looks like it's missing important parts, and would not compile as written (for example Exception e) and regex without quotes).
The data import developers guide https://mimno.github.io/Mallet/import-devel has sample code that should be a good starting point.
I read a file in JAVA and based on the users specifications, I convert the data in to a Linked List or a Tree, but how can I save the data in to the file (as a data structure), so that next time I read the data I do not have to make extra effort to parse the file.
You can save the data like this into file it is not a linked list but it will help to understand
//save persons
public void savePersons(){
try{
PersonsInfo p;
String line;
FileWriter fw= new FileWriter("input.txt");
PrintWriter pw= new PrintWriter(fw);
for (int i=0 ; i<persons.size();i++){
p =(PersonsInfo)persons.get(i);
line = p.getName() +","+ p.getAddress() +","+ p.getPhoneNum();
pw.println(line);
}
pw.flush();
pw.close();
fw.close();
} catch (IOException ioEx){
System.out.println(ioEx);
}
and you can retrieve the data like this and you dont need the parse the file every time
public class AddressBook{
ArrayList<PersonsInfo> persons;
public AddressBook (){
persons = new ArrayList <PersonsInfo> ();
loadPersons();
}
//Load Person
public void loadPersons (){
String tokens[]=null;
String name,address,phoneNum;
try{
FileReader fr= new FileReader("input.txt");
BufferedReader br= new BufferedReader(fr);
String line=br.readLine();
while (line !=null)
{
tokens = line.split(",");
name=tokens[0];
address=tokens[1];
phoneNum=tokens[2];
PersonsInfo p = new PersonsInfo(name,address,phoneNum);
persons.add(p);
line = br.readLine();
}
br.close();
fr.close();
}catch (IOException ioEx) {
System.out.println(ioEx);
}
}
It depends on how you want to store the data:
If you don't want to data to be stored in human readable form then you can go ahead with Serialization (example here). Java will take care of storing/constructing the objects/structures during write/read operations respectively.
If you want to store the data in human readable form then you can convert the data into let's say json and store it in String format. You can use Jackson's ObjectMapper class, e.g.:
ObjectMapper mapper = new ObjectMapper();
YourClass object = new YourClass();
FileOutputStream outputStream = new FileOutputStream("path_to_file");
outputStream.write(mapper.writeValueAsBytes(object));
//Read
YourClass persisted = mapper.readValue("path_to_file", YourClass.class);
Here's the example and here's Jackson's documentation.
You can use serialization which is a Java feature so very easy to use :
Save :
ObjectOutputStream oos = null;
try {
LinkedList<String> list = new LinkedList<>();
list.add("toto"); list.add("tata");
oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\..\\Doc\\list.ser"));
oos.writeObject(list);
} catch ... {
}finally (oos.close) ...{
}
Of course, if it's not a you change LinkedList to whatever you want
Load :
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("C:\\Users\\..\\Doc\\list.ser"));
final LinkedList<String> list = (LinkedList<String>) ois.readObject();
System.out.println(list.toString()); //[toto,tata]
} catch ... {
}finally (ois.close) ...{
}
At writing you use writeObject and at reading you use readObject + casting to the good type (so the order is important, if you write a List then String then Other, you may read List then String then Other)
Serialization Details
The exact thing I'm trying to do is to save a 2D array called num into a file called savedNumbers.data. Here is the code for saving to the .data file:
private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {
num[0][0] = Integer.parseInt(line00Tf.getText());
num[0][1] = Integer.parseInt(line01Tf.getText());
num[0][2] = Integer.parseInt(line02Tf.getText());
num[0][3] = Integer.parseInt(line03Tf.getText());
num[0][4] = Integer.parseInt(line04Tf.getText());
num[1][0] = Integer.parseInt(line10Tf.getText());
num[1][1] = Integer.parseInt(line11Tf.getText());
num[1][2] = Integer.parseInt(line12Tf.getText());
num[1][3] = Integer.parseInt(line13Tf.getText());
num[1][4] = Integer.parseInt(line14Tf.getText());
num[2][0] = Integer.parseInt(line20Tf.getText());
num[2][1] = Integer.parseInt(line21Tf.getText());
num[2][2] = Integer.parseInt(line22Tf.getText());
num[2][3] = Integer.parseInt(line23Tf.getText());
num[2][4] = Integer.parseInt(line24Tf.getText());
File outFile;
FileOutputStream fStream;
ObjectOutputStream oStream;
try {
outFile = new File("savedNumbers.data");
fStream = new FileOutputStream(outFile);
oStream = new ObjectOutputStream(fStream);
oStream.writeObject(num[0]);
oStream.writeObject(num[1]);
oStream.writeObject(num[2]);
JOptionPane.showMessageDialog(null, "File saved OK");
oStream.close();
} catch (IOException e) {
System.out.println("Error writing to file: " + e);
}
}
That code seems to be working well.
Now I want to view all the same numbers one array at a time in JOptionPane, so three lines of saved numbers will show, then OK is pressed and another three lines of saved numbers will show until there are no more.
I am having issues with calling the numbers from savednumbers.data
Here is the code for that:
//CODE FOR CALLING num FROM savedNums.data
private void showSavedNumsBtnActionPerformed(java.awt.event.ActionEvent evt) {
File inFile;
FileInputStream fStream;
ObjectInputStream oStream;
try{
inFile = new File("savedNumbers.data");
fStream = new FileInputStream(inFile);
oStream = new ObjectInputStream(fStream);
ArrayList <LottoPhase1> numList;
numList = (ArrayList<LottoPhase1>)oStream.readObject(); //THIS LINE HAVING PROBLEMS WITH
for(LottoPhase1 ph1:numList){
JOptionPane.showMessageDialog(null,
"Saved numbers " +
"Numbers: " + Arrays.toString(ph1.getNum())
);
}
oStream.close();
}
catch(IOException | ClassNotFoundException e){
JOptionPane.showMessageDialog(null, "Error: " + e);
}
I have also tried calling the ArrayList num, numList, aList, and neither worked.
The class LottoPhase1 is created and runs with no errors, and is fully debugged.
You are writing Arrays to the file, not ArrayList(s). This will not allow you to cast (ArrayList) back from the file because ObjectOutputStream saves the class name of the object with the object to allow it to deserialize it with ObjectInputStream
I would recommend either changing the data type of the object that you are writing to the file to be an ArrayList or to change the data type of the object that you are storing the data from the file in to an Array.
I am currently making a game in java with random world gen, at the beginning of the game I want it to store the tile ID, the X position, and the Y position so that when I re-load the game it will be able to generate it again.
When I write my file it all works but I have one issue, the output to the file is a weird combination of characters.
Code:
import java.io.*;
public class FileWrite {
public static FileWriter writeFile;
public static BufferedWriter write;
public static void recordItem(int blockID, int blockX, int blockY, String filePath, String fileName) throws Exception {
writeFile = new FileWriter("res/save/" + filePath+ fileName, true);
write = new BufferedWriter(writeFile);
write.write(blockID);
write.write(blockX);
write.write(blockY);
write.newLine();
write.flush();
}
}
Output in file:
#
`
?
?
?
?
?
?
?
?
?
How do I encode my FileWriter to UTF-8 so it displays numbers? Thanks for the help. :)
Just a suggestion, if you would like to make a little more robust form of your persistent info, you might consider object serialization. It's easier than it sounds. Just have a static inner class that implements Serializable, something like this:
static class JunkRec implements Serializable
{
private static final long serialVersionUID = 1L;
final int _blockID, _blockX, _blockY;
final String _filePath, _fileName;
public JunkRec(int blockID, int blockX, int blockY,
String filePath, String fileName)
{
_blockID = blockID;
_blockX = blockX;
_blockY = blockY;
_filePath = filePath;
_fileName = fileName;
}
#Override
public String toString() {
return String.format("id=%08d x=%04d y=%04d fp=%s fn=%s",
_blockID, _blockX, _blockY, _filePath, _fileName);
}
}
Now, one method to store a JunkRec...
public static void storeJunk(JunkRec jr)
{
try (
FileOutputStream fos = new FileOutputStream(
jr._filePath + jr._fileName + ".ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(jr);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
Another method to restore a JunkRec, given the filename.
public static JunkRec retrieveJunk(String filePath, String fileName)
{
try (
FileInputStream fis = new FileInputStream(
filePath + fileName + ".ser");
ObjectInputStream ois = new ObjectInputStream(fis);) {
return (JunkRec) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
And finally a little test driver in main()...
public static void main(String[] args)
{
// generate and restore 10 records
Random r = new Random();
List<String> names = new ArrayList<>();
/* do a few in two ways */
for (int i = 0; i < 5; ++i) {
int blk = r.nextInt(10000);
String fname = String.format("BLKID_%02d", i);
if (names.add(fname)) {
JunkRec jr = new JunkRec(
r.nextInt(10000),
r.nextInt(50),
r.nextInt(50),
"/tmp/",
fname);
storeJunk(jr);
System.out.println("Wrote: "+jr);
}
}
/* read them all back */
for (String fname : names) {
JunkRec jr = retrieveJunk("/tmp/", fname);
System.out.println("Retrieved: " + jr + " from " + fname);
}
/* clean up */
for (String fname : names) {
((File) new File("/tmp/" + fname + ".ser")).delete();
}
}
This is not production-quality code, but it shows how easy serialization can be. There are a gotchas, but in general Serialization is a solid solution for file-based persistence.
Just a suggestion. Have fun!
The write method writes a single character, so you're writing characters with the Unicode codepoint of blockID, blockX, blockY which is not what you want.
Whether your Writer is encoded as UTF-8 is not so relevant here, although it is always good to be explicit about encoding if you want your files to be portable across machines, so try new OutputStreamWriter(new FileOutputStream("res/save/" + filePath+ fileName, true), "UTF-8"); instead of creating a FileWriter directly. Creating it directly doesn't allow you to specify the encoding.
Instead do something like this:
writer.write(String.format("%d %d %d\n", blockID, blockX, blockY));
This will format your three numbers as one string on one line before sending it to the file.
Note that you shouldn't create a new Writer/BufferedWriter every time that you want to write a line. You should keep them in a class field and re-use the same writer. You also need to close the file after you are done with it, since the operating system has a limit to the number of files that you have open at the same time, and you will run out of that number quickly with your current code.
This question already has answers here:
Java FileInputStream ObjectInputStream reaches end of file EOF
(9 answers)
Closed 8 years ago.
Please have a look at below code
public class xina {
static name[] Name;
public static void main(String[] args) throws Exception {
Name = new name[3];
Name[0] = new name("Hugh", "Jackman");
Name[1] = new name("John", "TRavolta");
Name[2] = new name("Megh", "Ryne");
File ff = new File("object.txt");
FileOutputStream fo = new FileOutputStream(ff.getName());
ObjectOutputStream oo = new ObjectOutputStream(fo);
for (name dd : Name) {
System.out.println(dd.getfistName() + " " + dd.getlastName());
oo.writeObject(dd);
}
oo.close();
FileInputStream fi = new FileInputStream(ff.getName());
ObjectInputStream oi = new ObjectInputStream(fi);
name hh;
try {
while ((hh = (name) oi.readObject()) != null) {
System.out.println(hh.fistName);
}
} catch (EOFException e) {
System.out.println("file ended");
}
}
}
here "name" is class which save first name and last name.
How can i read the file without using exception.
My point is it is trying to read when no more objects exists look like null check is not sufficing the need.
THanks in advance.
while ((hh = (name) oi.readObject()) != null) {
The problem is here. readObject() returns null if you wrote a null, and not otherwise. The correct test for reading past end of stream is to catch EOFException.
Problem here is that the method InputStream#readObject does not return null object past EOF it always throws an Exception. The Simple solution to that is while serializing pass the size of the array first and read the size first and then the array of that size while de-serializing.
So while writing:
oo.writeObject(new Integer(Name.length));
for (name dd : Name) {
System.out.println(dd.getfistName() + " " + dd.getlastName());
oo.writeObject(dd);
}
while reading:
ObjectInputStream oi = new ObjectInputStream(fi);
Integer size = oi.readObject();
name hh;
for (int i=0;i<size;i++) {
hh= (Name) oi.readObject();
System.out.println(hh.fistName);
}
Hope this helps.