I need to implement a method called saveWorksToFile according to the Javadoc in the code. The format of the output written to the file should be the following this pattern:
where ARTIST_NAME is the name of the artist, NUM_WORKS is the number of works
of that artist, and WORK_1, WORK_2, etc. are the toString representations of
each of that artist's works.
The last work should not have a line separator after it.
If an artist has no works, then the first three lines of the above format should
be written, where the “-----” line has a line separator after it.
And this is the code I have:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
public class Artist {
static class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
#Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
/**
* Writes the toString representation of each of this artist's works to the
* given writer. Also writes header lines containing the artist's name and
* number of works.
*
* If an IOException occurs, the message "IOException occurred" should be
* printed to System.out.
*
* #param writer writer to write this artist's works to
*/
public void saveWorksToFile(Writer writer) {
// write your code here
try {
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(this.name);
buffer.newLine();
buffer.write("works: " + this.works.size());
buffer.close();
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
}
I got these errors:
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
I have difficulties on making a new line, I tried both \n and newLine() method but it doesn't work. And also showing the number of works on the list should be correct. And for the loop, I think I should use for loop in this case to loop over the art works.
Any hints/ help would be great, thank you!
Below is my code for method saveWorksToFile. It is the only part of the code in your question that I changed. (Notes after the code.)
public void saveWorksToFile(Writer writer) {
try {
writer.write(this.name);
writer.write(System.lineSeparator());
writer.write("works: " + this.works.size());
writer.write(System.lineSeparator());
writer.write("---");
writer.write(System.lineSeparator());
boolean first = true;
for (Work work : works) {
if (first) {
first = false;
}
else {
writer.write(System.lineSeparator());
}
writer.write(work.toString());
}
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
You are not meant to wrap the Writer parameter in a BufferedWriter. In general, for any method, you usually should not need to cast the parameter. Hence, in the above code, I use only the methods of class Writer. Also note that I do not close Writer since that should be left to the code that invoked method saveWorksToFile.
In order to write a line separator, I call method lineSeparator of class java.lang.System.
In order to print all the artist's works one per line, I use a loop.
In order to ensure that the last entry in the artist's list of works is written without a line separator, the first work is written without a line separator and every subsequent work is written with a preceding line separator.
Here is a method I wrote to test the above code. It uses class java.io.StringWriter which is a subclass of Writer since class Writer is abstract and has no public constructor. In general, you cannot instantiate an abstract class. You need to use a concrete subclass. I use StringWriter so as to be able to print its contents easily to the screen. You can use class java.io.FileWriter if you want to write to an actual file.
/**
* import java.io.StringWriter
*/
public static void main(String[] args) {
Artist artist = new Artist("Vincent van Gogh");
StringWriter sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Claude Monet");
Work work = new Work("Bridge over a Pond of Water Lilies", 1899, "Oil on canvas");
artist.addWork(work);
work = new Work("Impression, Sunrise", 1872, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Henri Matisse");
work = new Work("Woman with a Hat", 1905, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
}
This is the output I got when I ran the above main method.
Vincent van Gogh
works: 0
---
Claude Monet
works: 2
---
Bridge over a Pond of Water Lilies|1899|Oil on canvas
Impression, Sunrise|1872|Oil on canvas
Henry Matisse
works: 1
---
Woman with a Hat|1905|Oil on canvas
you can use json format to save your data easily and orginized like this
public void saveWorksToFile(OutputStreamWriter writer) {
// write your code here
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("ARTIST_NAME",this.name);
jsonObject.put("NUM_WORKS",this.works.size());
for (int i=0;i<works.size();i++) {
jsonObject.put("work_" + i, works.get(i).toString());
// you can save work as a byte array or json string so you could easily import the data back
}
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(jsonObject.toString()+"\n");
buffer.close();
}
catch (IOException | JSONException e) {
System.out.println("IOException occurred");
}
}
public Artist readFromFile(File file){
Artist artist = null;
FileReader fileReader = null;
String line= null;
BufferedReader bufferedReader;
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
line = bufferedReader.readLine();
while (line != null){
line += "\n";
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(line);
String name = jsonObject.get("ARTIST_NAME").toString();
int works_num = Integer.parseInt(jsonObject.get("NUM_WORKS").toString());
// here you can import the works as a string.
artist = new Artist(name);
} catch (JSONException e) {
e.printStackTrace();
}
line = bufferedReader.readLine();
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return artist;
}
My advice is that you separate classes, sometimes it is difficult to figure out problems. I separated them like this.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Artist {
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
public void saveWork(){
try{
BufferedWriter writer = new BufferedWriter(
new FileWriter("path where want to save"));
writer.write(this.name);
writer.newLine();
writer.write("works: " + this.works.size());
writer.newLine();
this.works.forEach(work -> {
try {
writer.write(work.name);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
#Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
public class Main {
public static void main(String[] args) {
Work work1 = new Work("Fast1",2019,"ss");
Work work2 = new Work("Fast2",2019,"ss");
Artist artist = new Artist("Artist_Tom_Cruise");
artist.addWork(work1);
artist.addWork(work2);
artist.saveWork();
}
}
Related
import java.util.*;
import java.io.*;
class Book implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String author;
public String getAuthor() {
return author;
}
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public void disPlay() {
System.out.print("Book name : " + name);
System.out.println("\tAuthor name : " + author);
}
}
public class Print {
public static void main(String[] args) throws Exception {
writeList();
List<Book> list = readList();
for (Book obj : list)
System.out.println(obj);
}
public static List<Book> readList() throws Exception {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.dat"));
#SuppressWarnings("unchecked")
List<Book> readObject = (List<Book>) in.readObject();
in.close();
return readList();
}
public static void writeList() throws Exception {
List<Book> list = new ArrayList<>();
ObjectOutputStream out = null;
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter the book, author name : ");
String name = scan.next();
String author = scan.next();
list.add(new Book(name, author));
System.out.print("If you want to save to the list -1, if you don't want, enter 1 : ");
int choice = scan.nextInt();
out = new ObjectOutputStream(new FileOutputStream("object.dat"));
out.flush();
out.close();
System.out.print("Save the list to a file");
}
}
}
I try to get the ArrayList object stored in the file (object.dat), save the Book object in the ArrayList, and then save the ArrayList where the Book object is stored in the file before the end of the program.
The result I want is,
[Results When Program First Runs]
There are no saved values
Enter the book, author name : Harrypotter jkrowling
If you want to save to the list -1, if you don't want, enter 1 : -1
Save the list to a file
and,
[Results on Second and Later]
---Outputs the value stored in the file name---
Book name : Harrypotter
Author name : jkrowling
Enter the book, author name : Twilight StephenieMeyer
If you want to save to the list -1, if you don't want, enter 1 : 1
Save the list to a file
I'd like to print it out like this, but what should I do?
Here is the general way of writing to file in java.
import java.io.FileWriter; // Import the FileWriter class
try {
FileWriter myWriter = new FileWriter("filename.txt");
myWriter.write("Write into file here! ");
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
To simplify your code and avoid boilerplates I’d recommend you to look towards specific tools and libs working with files.
There is a good article about loading and reading files using Spring:
Spring Resource
For writing content to a file look towards eg “Apache Commons IO” library provides useful helper methods like:
FileUtils.write(new File(“File.txt"), "Content Text", "UTF-8");
In any case investigate these tools and then think about adopting your requirements in them.
try {
FileWriter writer = new FileWriter("Book.txt");
for(int i = 0 ; i < arraylist.size(); i++){
writer.write(arraylist.get(i).getName();
writer.write(arraylist.get(i).getAuthor();
}
myWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
As a part of my assignment I had to store objects of an array in a flat-file and retrieve them when certain criteria was met. I can save the objects fine but when retrieving them I have an issue with getting more than one value, I understand what is going wrong but I am struggling to find a solution. Here is the concept of whats happening.
Button no 10,A (R1S10 in the code)is my testing button, When I click it it creates an event that I will show below.
Click event for button 10A -
private void R1S10ActionPerformed(java.awt.event.ActionEvent evt) {
seats.add(seat1);
if (R1S10.getBackground().equals(Color.red) &&(IsSeatBooked().equals("true"))){
Component frame = null;
JOptionPane.showMessageDialog(frame, "Seat UnBooked");
seat1.setBooked("false");
seat1.setName("");
R1S10.setBackground(Color.yellow);
try {
reader();
writer();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Component frame = null;
String name = JOptionPane.showInputDialog(frame, "Please enter name of Customer booking");
if (name.isEmpty()) {
JOptionPane.showMessageDialog(frame, "No value entered");
} else if (name != null) {
seat1.setName(name);
seat1.setBooked("true");
R1S10.setBackground(Color.red);
JOptionPane.showMessageDialog(frame, "Your Booking has been placed");
try {
writer();
reader();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Followed by the screen below -
Outcome -
And when the button is pressed again -
I am using three methods in this SeatingPlan.java - writer(),reader() and IsSeatBooked().
SeatingPlan -
public class SeatingPlan extends javax.swing.JFrame {
/**
* Creates new form SeatingPlan
*/
String seatNo, name, bookedSeat;
FileWriter fileWriter = null;
List<Seat> seats = new ArrayList<Seat>();
//Seat Object Declaration
Seat seat1 = new Seat("R1S10","","false");
Seat seat2 = new Seat("R1S9", "", "false");
String fileName = "seat.csv";
writer -
public void writer() throws IOException {
//Delimiter used in CSV file
final String NEW_LINE_SEPARATOR = "\n", COMMA_DELIMITER = ",";
//CSV file header
final String FILE_HEADER = "seatID,name,booked";
//fileName = System.getProperty("user.home") + "/seat.csv";
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a new student object list to the CSV file
for (Seat seat : seats) {
fileWriter.append(String.valueOf(seat.getSeatID()));
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.getName());
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.isBooked());
fileWriter.append(NEW_LINE_SEPARATOR);
}
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
fileWriter.flush();
fileWriter.close();
}
}
reader -
public void reader() {
//Delimiter used in CSV file
final String COMMA_DELIMITER = ",";
//Student attributes index
final int SEAT_ID_IDX = 0;
final int SEAT_NAME_IDX = 1;
final int SEAT_BOOKED = 2;
//private static final int STUDENT_LNAME_IDX = 2;
BufferedReader fileReader = null;
try {
//Create a new list of student to be filled by CSV file data
List<Seat> seats = new ArrayList<>();
String line = "";
//Create the file reader
fileReader = new BufferedReader(new FileReader(fileName));
//Read the CSV file header to skip it
fileReader.readLine();
//Read the file line by line starting from the second line
while ((line = fileReader.readLine()) != null) {
//Get all tokens available in line
String[] tokens = line.split(COMMA_DELIMITER);
if (tokens.length > 0) {
//Create a new seat object and fill his data
Seat seat = new Seat(tokens[SEAT_ID_IDX],
tokens[SEAT_NAME_IDX], tokens[SEAT_BOOKED]);
seats.add(seat);
seatNo = tokens[SEAT_ID_IDX];
//System.out.println("Seat Number: " + seatNo);
bookedSeat = tokens[SEAT_BOOKED];
}
}
//Print the new student list
for (Seat seat : seats) {
System.out.println(seat.toString());
}
} catch (Exception e) {
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
}//end reader
SeatingPlan - This if where I have tried to have the arguments controlling the outcome but IsBooked is colliding when multiple seats are selected.
public SeatingPlan() throws IOException {
setVisible(true);
initComponents();
//reader();
ColourSectionGold();
ColourSectionBronze();
reader();
if(R1S10.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true"))){ R1S10.setBackground(Color.red);}
//if(R1S9.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true2"))){ R1S9.setBackground(Color.red);}
}
IsSeatBooked -
public String IsSeatBooked(){
return bookedSeat;
}//end IsSeatBooked
Im using the method above as my argument to see whether a seat is booked or not, but when a new seat is click it sets the whole value of 'bookedSeat' - which leaves the system not working correctly. I understand the code is not very efficient but is there any temporary fix for this problem, if I have explained it correctly.
Also I will include my class for Seat -
public class Seat {
private String seatID;
private String booked;
private String name;
private int price;
public Seat(String seatID,String name,String booked){
this.seatID = seatID;
this.booked = "";
this.name = name;
this.price = price;
}
public String getSeatID() {
return seatID;
}
public void setSeatID(String seatID) {
this.seatID = seatID;
}
public String isBooked() {
return booked;
}
public void setBooked(String booked) {
this.booked = booked;
}
public String getStatus(){
return booked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice() {
this.price = price;
}}//end class Seat
And a look at the CSV file that is created -
I wish to be able to click more than one button and save its state, Button 10 works fine at the moment, but as IsBooked only has one value at a time it clashes.
If you took the time to check this out, I appreciate it. Any constructive criticism is helpful and any ideas would be great!
Thanks,
Paddy.
Too much code to look at to see exactly what you are doing.
Instead of using your csv file, you could create a Properties file. The Propertiesfile will store the data in the form of:
key:data
So in your case the key would be the id: A1, A2... and the data would be the name of the person who booked the seat.
So the file would start out as empty. When you create the GUI you would create a loop that checks each id to see if an entry is found in the Properties field. If it is found then you display the seat as taken, otherwise it is empty.
Then whenever you want to book a seat you just use the setProperty(...) method.
The Properties class has load(...) and store(...) methods.
So the Properties class allows you to easily manage a flat file database with minimal effort.
Note, you would never have variable names like R1S10. That would requirement 100 different variables with if/else statements. Instead you would extend JButton and pass in the row and seat as parameters the button. Then in the ActionListener for the button you can access the row/seat information to built the ID used as the key for the properties file.
Edit:
Couldn't quite make the loop that checks if the ID is in the properties file.
If the property is null, the seath is empty.
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("A2", "Smith");
properties.setProperty("C3", "Jones");
String[] rows = { "A", "B", "C", "D" };
int seats = 4;
for (int row = 0; row < rows.length; row++)
{
for (int seat = 1; seat <= seats; seat++)
{
String key = rows[row] + seat;
String property = properties.getProperty( key );
System.out.println(key + " : " + property);
}
}
}
}
I'm working on a program that saves two words into a HashMap. I need to be able to take the HashMap key and value and write it into a file as "key:value" format. When my save() method is called, the HashMap contents are supposed to be written into the file whose name was given as parameter to the constructor. The method returns false if the file can't be saved; otherwise it returns true. However, its not working if the File does not exist. It's also not saving changes made to an existing file. I'm not understanding how to read/write files too well... Thank you.
package dictionary;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Scanner;
public class MindfulDictionary {
private HashMap<String, String> words;
private File file;
public MindfulDictionary() {
this.words = new HashMap<String, String>();
}
public MindfulDictionary(String file) {
this.file = new File(file);
this.words = new HashMap<String, String>();
}
public boolean load() {
try {
Scanner fileReader = new Scanner(this.file);
while (fileReader.hasNextLine()) {
String line = fileReader.nextLine();
String[] parts = line.split(":"); // the line is split at :
String word = parts[0];
String trans = parts[1];
this.add(word, trans);
}
} catch (Exception e) {
System.out.println("nope");
}
return true;
}
public boolean save() {
boolean saved = true;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(this.file.getName(), true));
for (String key : this.words.keySet()) {
writer.write(key + ":" + this.words.get(key) + "\n");
writer.newLine();
writer.flush();
writer.close();
}
} catch (Exception e) {
}
return saved;
}
public void add(String word, String translation) {
if ((!this.words.containsKey(word))) {
this.words.put(word, translation);
}
}
public String translate(String word) {
if (this.words.containsKey(word)) {
return this.words.get(word);
} else if (this.words.containsValue(word)) {
for (String key : this.words.keySet()) {
if (this.words.get(key).equals(word)) {
return key;
}
}
}
return null;
}
public void remove(String word) {
if (this.words.containsKey(word)) {
this.words.remove(word);
} else if (this.words.containsValue(word)) {
String remove = "";
for (String key : this.words.keySet()) {
if (this.words.get(key).equals(word)) {
remove += key;
}
}
this.words.remove(remove);
}
}
}
Notice this part of your code,
try {
writer = new BufferedWriter(new FileWriter(this.file.getName(), true));
for (String key : this.words.keySet()) {
writer.write(key + ":" + this.words.get(key) + "\n");
writer.newLine();
writer.flush();
writer.close(); // !!
}
} catch (Exception e) {
}
Here, you are calling close() on the BufferedWriter object. You can not use the object after you have called close() on it.
Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown.
Read more about close() here.
Also, since you are catching all the exceptions and not doing anything with them, you did not notice the IOException . In future NEVER do this. At the least log any exception that occurs. This will help you with your debugging.
This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 5 years ago.
sorry to bother you, once again I need help on the Java language , more precisely on the file structured as the title .
The error in question is that after you have stored more than once , I read reports an error (of course putting in append mode) , and does so even if I do all in the main program ...
My program consists of three classes in three files:
Alluno.java:
import java.io.Serializable;
class Alunno implements Serializable {
private String nome, cognome, data_nascita, indirizzo, residenza, telefono;
public Alunno() {
nome = ""; cognome = ""; data_nascita = ""; indirizzo = ""; residenza = ""; telefono = "";
}
public void setNome(String nome) {
this.nome = nome;
}
void setCognome(String cognome) {
this.cognome = cognome;
}
void setData_Nascita(String data_nascita) {
this.data_nascita = data_nascita;
}
void setIndirizzo(String indirizzo) {
this.indirizzo = indirizzo;
}
void setResidenza(String residenza) {
this.residenza = residenza;
}
void setTelefono(String telefono) {
this.telefono = telefono;
}
}
File.java:
import java.io.*;
class File {
private int dim;
public Alunno nuovoAlunno() throws IOException {
BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
Alunno a = new Alunno();
System.out.println("***Inserimento nuovo alunno***");
System.out.format("Nome: ");
a.setNome(t.readLine());
System.out.format("Cognome: ");
a.setCognome(t.readLine());
System.out.format("Data di nascita: ");
a.setData_Nascita(t.readLine());
System.out.format("Indirizzo: ");
a.setIndirizzo(t.readLine());
System.out.format("Residenza: ");
a.setResidenza(t.readLine());
System.out.format("Telefono: ");
a.setTelefono(t.readLine());
return a;
}
public void sciviFile(Alunno a) {
try {
FileOutputStream f = new FileOutputStream("istituto.dat", true);
ObjectOutputStream fOUT = new ObjectOutputStream(f);
fOUT.writeObject(a);
fOUT.flush();
fOUT.close();
} catch (Exception e) {
System.out.println("Eccezione scrittura: " + e.getMessage());
}
}
public void leggiFile() {
Alunno a;
try {
FileInputStream f = new FileInputStream("istituto.dat");
ObjectInputStream fIN = new ObjectInputStream(f);
while (true) {
try {
a = (Alunno) fIN.readObject();
dim++;
System.out.println("Dimensione file: " + dim);
} catch (EOFException e) {
break;
}
}
f.close();
} catch (Exception e) {
System.out.println("Eccezione lettura: " + e.getMessage());
}
}
}
IstitutoScolastico.java:
import java.io.*;
public class IstitutoScolastico {
public static void main(String[] args) throws IOException {
File f = new File();
//f.sciviFile(f.nuovoAlunno());
f.leggiFile();
}
}
OUTPUT:
Dimensione file: 1
Eccezione lettura: invalid type code: AC
I do not read more than one object if I put in append mode, where did I go wrong?
Ah, anyway sorry for the grammatical errors, but I'm Italian and I helped with google translate!
The problem is that ObjectOutputStream writes a header to the file in it's constructor.
Since you call the constructor for each Alunno you append, you write a new header to the file too.
However ObjectInputStream expects only one header(at the start of the file).
If you don't want to change much in your code, you should create a new ObjectInputStream for each Alunno you read, change the code in your File class:
public void leggiFile() {
Alunno a;
try {
FileInputStream f = new FileInputStream("istituto.dat");
try {
while (true) {
// the header is read in the constructor
ObjectInputStream fIN = new ObjectInputStream(f);
a = (Alunno) fIN.readObject();
dim++;
System.out.println("Dimensione file: " + dim);
}
} catch (EOFException e) { }
f.close();
} catch (Exception e) {
System.out.println("Eccezione lettura: " + e.getMessage());
}
}
A alternative would be to skip 2(?) shorts (4(?) bytes) from the FileInputStream, but if the definition of the header should change (although this seems unlikely), you might have to change your code.
Another alternative would be to read all the Alunnos that are already in the file and then write all Alunnos (including the new one) to the File starting at the beginning of the file. But this may not be as fast as you wish.
For detailed information you can read http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html and http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html
One last tip: If you use Java SE 7 (or higher) consider using try-with-resources for your streams.
So I am supposed to make 3 classes and am given a 4th class to use for a user interface. One class (DBBinding) is supposed to have a String key and String value and take something like name:Alien or star: harry dean and make name or star be the "key" and the other is the "value" the next class (DBrecord) is to hold a group of these "bindings" as one record. I have chosen to keep a group of these bindings in a ArrayList. The third class(DBTable) is another ArrayList but of . I am at the point where I am reading in a line of txt from file where each line of txt is going to be one DBrecord that we know will be in correct formatting(key:value, key:value, key:value, and so on).
Where I am having trouble is within the DBrecord class. I have a method(private void addBindingToRecord(String key_, String value_)) that is called from (public static DBrecord createDBrecord(String record)) from within the DBrecord class here are each methods code.
I am having trouble with the addBindingToRecord method ... it null pointer exceptions on the first time used. I think it has to do with sytax and how I am calling the "this.myDBrecord.add(myDBBinding);"... have tried it multiple ways with same result....
public static DBrecord createDBrecord(String record)//takes a string and breaks it into DBBindings and makes a record with it.
{
DBrecord myRecord=new DBrecord();
String temp[];
temp=record.split(",",0);
if(temp!=null)
{
for(int i=0; i<Array.getLength(temp); i++)
{
System.out.println("HERE");//for testing
String temp2[];
temp2=temp[i].split(":",0);
myRecord.addBindingToRecord(temp2[0], temp2[1]);
}
}
return myRecord;
}
private void addBindingToRecord(String key_, String value_)
{
DBBinding myDBBinding=new DBBinding(key_, value_);
if(myDBBinding!=null)//////////////ADDED
this.myDBrecord.add(myDBBinding);///Here is where my null pointer exception is.
}
I am going to post the full code of all my classes here so you have it if need to look at. Thank for any help, hints, ideas.
package DataBase;
import java.io.*;
public class CommandLineInterface {
public static void main(String[] args) {
DBTable db = new DBTable(); // DBTable to use for everything
try {
// Create reader for typed input on console
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line;
while (true) {
int length = 0;
int selectedLength = 0;
// YOUR CODE HERE
System.out.println("\n" + length + " records (" + selectedLength + " selected)");
System.out.println("r read, p print, sa select and, so select or, da ds du delete, c clear sel");
System.out.print("db:");
line = reader.readLine().toLowerCase();
if (line.equals("r")) {
System.out.println("read");
String fname;
System.out.print("Filename:");
//fname = reader.readLine();////ADD BACK IN AFTER READ DEBUGED
// YOUR CODE HERE
fname="movie.txt";
db.readFromFile(fname);
}
else if (line.equals("p")) {
System.out.println("print");
// YOUR CODE HERE
DBTable.print();
}
else if (line.equals("da")) {
System.out.println("delete all");
// YOUR CODE HERE
}
else if (line.equals("ds")) {
System.out.println("delete selected");
// YOUR CODE HERE
}
else if (line.equals("du")) {
System.out.println("delete unselected");
// YOUR CODE HERE
}
else if (line.equals("c")) {
System.out.println("clear selection");
/// YOUR CODE HERE
}
else if (line.equals("so") || line.equals("sa")) {
if (line.equals("so")) System.out.println("select or");
else System.out.println("select and");
System.out.print("Criteria record:");
String text = reader.readLine(); // get text line from user
// YOUR CODE HERE
}
else if (line.equals("q") || line.equals("quit")) {
System.out.println("quit");
break;
}
else {
System.out.println("sorry, don't know that command");
}
}
}
catch (IOException e) {
System.err.println(e);
}
}
}
package DataBase;
import java.util.*;
import java.io.*;
public class DBTable {
static ArrayList<DBrecord> myDBTable;
public DBTable()
{
ArrayList<DBrecord> myDBTable= new ArrayList<DBrecord>();
}
public static void addRecordToTable(DBrecord myRecord)//added static when added addRecordToTable in readFromFile
{
if(myRecord!=null)
{myDBTable.add(myRecord);}
}
public static void readFromFile(String FileName)
{
try
{
FileReader myFileReader=new FileReader(FileName);
String line="Start";
BufferedReader myBufferdReader=new BufferedReader(myFileReader);
while(line!="\0")
{
line=myBufferdReader.readLine();
if(line!="\0")
{
System.out.println(line);//TEST CODE
addRecordToTable(DBrecord.createDBrecord(line));// made addRecordToTable static.
}
}
}catch(IOException e)
{System.out.println("File Not Found");}
}
public static void print()
{
if (myDBTable==null)
{
System.out.println("EMPTY TABLE");
return;
}
else
{
for (int i=0; i<myDBTable.size(); i++)
{
System.out.println(myDBTable.get(i).toString());
}
}
}
}
package DataBase;
import java.util.*;
import java.lang.reflect.Array;
//import DataBase.*;//did not help ... ?
public class DBrecord {
boolean select;
String key;
//need some type of collection to keep bindings.
ArrayList<DBBinding> myDBrecord;
public DBrecord()
{
//DBrecord myRecord=new DBrecord();
select=false;
ArrayList<DBBinding> myDbrecord=new ArrayList<DBBinding>();
}
private void addBindingToRecord(String key_, String value_)
{
DBBinding myDBBinding=new DBBinding(key_, value_);
//System.out.println(myDBBinding.toString());//for testing
if(myDBBinding!=null)//////////////ADDED
this.myDBrecord.add(myDBBinding);
System.out.println(key_);//for testing
System.out.println(value_);//for testing
}
public String toString()
{
//out put key first then all values in collection/group/record. use correct formatting.
StringBuilder myStringbuilder=new StringBuilder();
for (int i=0;i<this.myDBrecord.size();i++)
{
myStringbuilder.append(myDBrecord.get(i).toString());
myStringbuilder.append(", ");
}
myStringbuilder.delete(myStringbuilder.length()-2, myStringbuilder.length()-1);//delete last ", " thats extra
return myStringbuilder.toString();
}
public static DBrecord createDBrecord(String record)//takes a string and breaks it into DBBindings and makes a record with it.
{
//System.out.println("HERE");//for testing
DBrecord myRecord=new DBrecord();
String temp[];
temp=record.split(",",0);
if(temp!=null)
{
//System.out.println("HERE");//for testing
//for(int i=0; i<Array.getLength(temp); i++) ///for testing
//{System.out.println(temp[i]);}
for(int i=0; i<Array.getLength(temp); i++)
{
System.out.println("HERE");//for testing
String temp2[];
temp2=temp[i].split(":",0);
System.out.println(temp2[0]);//for testing
System.out.println(temp2[1]);//for testing
myRecord.addBindingToRecord(temp2[0], temp2[1]);
System.out.println(temp2[0]+ " "+ temp2[1]);////test code
}
}
return myRecord;
}
}
package DataBase;
public class DBBinding {
private String key;
private String value;
public DBBinding(String key_, String value_)
{
key =key_;
value=value_;
}
public String getKey()
{return key;}
public String getValue()
{return value;}
public String toString()
{return key+": "+value;}
}
In your constructor: ArrayList<DBBinding> myDbrecord=new ArrayList<DBBinding>();
You only create a local variable named myDbrecord and initialize it, instead of initializing the field myDBrecord.
You probably wanted instead:
myDBrecord = new ArrayList<DBBinding>();