Print To File in Java - java

i have a problem in my java exercise.
i need to print a multiply contact information to a file, but when i print more then 1 contact, only 1 contact is displayed in the file..
i tried to debug that but i cant find any mistake
i will put the code of my classes here:
This is Demo Class which i run the code from
public class Demo {
public static void main(String[] args) {
System.out.println("Insert number of Contacts:");
Scanner scanner = new Scanner(System.in);
int val = scanner.nextInt();
Contact[] contacts = new Contact[val];
for(int i = 0 ; i < val; i++) {
System.out.println("Contact #"+(i+1));
System.out.print("Owner: \n");
String owner = scanner.next();
System.out.print("Phone number: \n");
String phoneNum = scanner.next();
System.out.print("Please Select Group:\n"
+ "1 For FRIENDS,\n" +
"2 For FAMILY,\n" +
"3 For WORK,\n" +
"4 For OTHERS");
int enumNum = scanner.nextInt();
Group group;
switch(enumNum) {
case 1:
group=Group.FRIENDS;
break;
case 2:
group=Group.FAMILY;
break;
case 3:
group=Group.WORK;
break;
default:
group=Group.OTHERS;
}//switch end
contacts[i] = new Contact(owner,phoneNum,group);
}//loop end
System.out.println("Insert File name");
String fileName = scanner.next();
File f=null;
for(int i = 0 ; i < val; i++) {
if(i==0) {
f = new File(fileName);
contacts[0].Save(fileName);
}
else {
contacts[i].Save(f);
}
}
}
}
This is Contact Class:
enum Group {
FRIENDS,
FAMILY,
WORK,
OTHERS
};
public class Contact {
private String phoneNumber,owner;
private Group group;
PrintWriter pw = null;
public Contact(String owner ,String phoneNumber,Group group) {
setPhoneNumber(phoneNumber);
setOwner(owner);
setGroup(group);
}
public Contact(String fileName) {
File file = new File(fileName+".txt");
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public Contact(File file) {
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
if(f.createNewFile()) {
System.out.println("File created");
pw = new PrintWriter(f); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
}
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}
public void Save(File f) {
PrintWriter pw=null;
try {
pw = new PrintWriter(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.println(phoneNumber+"\n"+owner+"\n"+group);
pw.close();
}
public String toString() {
return phoneNumber+"\n"+owner+"\n"+group;
}
}

Every time you create PrintWriter the file is being overwritten. Since you create a new PrintWriter for each contact, the file contains only the last contact information. What you should do is to create PrintWriter only once and use it for all contacts.
Firstly, let's create a new save method with such signature:
public void save(PrintWriter writer)
I have also used the lowercase name of the method due to Java naming convention.
Now the implementation of save method will look like this:
writer.println(phoneNumber);
writer.println(owner);
writer.println(group + "\n\n\n");
Then we should replace the usage of Save method with the new one. Here is your code:
String fileName = scanner.next();
File f = null;
for (int i = 0; i < val; i++) {
if(i == 0) {
f = new File(fileName);
contacts[0].Save(fileName);
} else {
contacts[i].Save(f);
}
}
In order to fix the issue we can change it like this:
String fileName = scanner.next();
File file = new File(fileName);
try (PrintWriter writer = new PrintWriter(file)) {
for (int i = 0; i < val; i++) {
contacts[i].save(writer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
I have also used try-with-resources which closes the PrintWriter automatically.

From the Javadoc of the constructor of PrintWriter:
public PrintWriter​(File file)
Parameters: file - The file to use as the destination of this writer. If the file exists then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.
In the Save function you create a PrintWriter everytime. So everytime the file is truncated, and then you lose the contact you saved before.

Since File I/O classes in java use Decorator Design pattern, you can use a FileWriter to take advantage of appending to a file. So you can use this code for Save() method :
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
//System.out.println("File created"); You don't need to create new file.
FileWriter fw=new FileWriter(f,true):// second argument enables append mode
pw = new PrintWriter(fw); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}

Related

It keeps me looping even though I don't have any loops

I don't know what is wrong but it keeps me looping even though I pressed or entered 1 and I want it to call the subclass agent it doesn't but when I press 2 it calls the subclass what is wrong here I've been at it for 5-7hrs I think and my eyes be balling
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
class Person
{
protected String agentId = "20860132";
protected String password = "20020729" ;
protected String address;
public Person(String agentId,String password, String address)
{
this.agentId = agentId;
this.password = password;
this.address = address;
Scanner input = new Scanner(System.in);
System.out.println("[1]AGENT");
System.out.println("[2]CUSTOMER");
int choice = input.nextInt();
//here is where the code loops it just keeps repeating this lines
"System.out.println("[1]AGENT"); System.out.println("[2]CUSTOMER");"
if(choice == 1)
{
Agent agent = new Agent("Niel", "diko alam", "umay");
}
else if(choice == 2)
{
System.out.println("POTANGINA");
}
}
}
the block of code up here is suppose to call this class
class Agent extends Person
{
public Agent(String agentId, String password, String address)
{
super(agentId, password, address);
Scanner input2 = new Scanner(System.in);
System.out.println("[LOGIN]");
System.out.print("ENTER AGENT ID:");
int id = input2.nextInt();
System.out.print("ENTER PASSWORD:");
int pass = input2.nextInt();
if(id == 20860132 && pass == 20020729)
{
Scanner input = new Scanner(System.in);
System.out.println("[1]ADD CAR");
System.out.println("[2]SCHEDULE");
System.out.println("[3]RECORDS");
int choice2 = input.nextInt();
if(choice2 == 1)
{
boolean stopFlag = false;
do
{
List<String>cars = new ArrayList<String>();
System.out.println("[CARS]");
cars.add("Tayota");
cars.add("Hillux");
cars.add("Bugatti");
System.out.println(cars);
System.out.println("Enter Car:");
String car = input.nextLine();
cars.add(car);
System.out.println("Would you like to add more?");
System.out.println("[1]YES");
System.out.println("[2]NO");
String choice3 = input.nextLine();
addCar(cars);
if(!choice3.equals(1))
stopFlag = true;
}while(!stopFlag);
}
}
else
{
System.out.println("INCORRECT PLEASE TRY AGAIN.");
}
}
public void addCar(List<String> cars)
{
try
{
FileWriter fw = new FileWriter("cars.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(cars);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void schedule(String schedule)
{
try
{
FileWriter fw = new FileWriter("schedule.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(schedule);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void records(String record)
{
try
{
FileWriter fw = new FileWriter("records.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(record);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class Customer extends Person
{
private String customerId;
public Customer(String agentId, String password, String address, String customerId)
{
super(agentId, password, address);
this.customerId = customerId;
}
public void setCustomerId(String customerId)
{
this.customerId = customerId;
}
public String getCustomerId()
{
return customerId;
}
public void rentCar(String car)
{
try
{
FileWriter fw = new FileWriter("cars.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(car);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void viewSchedule(String schedule)
{
try
{
FileWriter fw = new FileWriter("schedule.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(schedule);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void extend(String record)
{
try
{
FileWriter fw = new FileWriter("records.txt", true);
PrintWriter pw = new PrintWriter(fw);
pw.println(record);
pw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Here is the main method
public class Finals
{
public static void main(String[] args)
{
Person person = new Person("20860132", "h208f32", "San luis");
Agent agent = new Agent("20860132", "h208f32", "San luis");
}
}
First line in the constructor of Agent calls super, which is the constructor of Person that will ask for input 1 and 2 again. That is your 'loop'. When you select 1, it will start creating another Agent object which will do the same thing again. If you keep selecting '1' you will never get past the super call in Agent.
Put the printing/input logic somewhere else, like in your main method. Constructors should be simple. For example, the logic in your Person constructor, move that to a static method in your Finals class (public static void createPerson) with the same arguments as what the constructor now has, and then call that from your main method instead of new Person. There is still much to improve beyond that, but that will probably fix your 'loop'.

PrintWriter printing "line.separator" twice in file

I have a method called saveAgendaDataArrayList() which is suposed to save the data from an ArrayList in a TXT file as following.
public void saveAgendaDataArrayList(String path, ArrayList<Contact> agendaDataArrayList) {
try {
if(agendaDataArrayList!=null) {
File file = new File(path);
PrintWriter p = new PrintWriter(file);
int count = agendaDataArrayList.size();
for(int i=0; i<count; i++) {
Contact temp = new Contact();
temp = agendaDataArrayList.get(i);
p.println(temp.getIdAdress()+";"+temp.getContactType()+";"+temp.getName()+";"+temp.getBirthdayDay()+
";"+temp.getBirthdayMonth()+";"+temp.getBirthdayYear()+";"+temp.getTel1()+";"+temp.getTel2()+
";"+temp.getNeigborhood()+";"+temp.getAddress()+";"+temp.getCep()+";"+temp.getEmail()
+";"+temp.getOtherInformation()+";"+temp.getCreationDate()+";");
}
p.close();
} else {
File file = new File(path);
PrintWriter p = new PrintWriter(file);
p.print("empty agenda");
p.close();
}
} catch (IOException e) {
e.printStackTrace();
}
However, when it runs, I have some new lines coming from I don't know where. Look below.
1;1;Guilhermee;00;00;;8666666;;sem bairro;;;;;12-09-2019 04:45:47;
2;1;Gabriella;00;00;;;;Morada do Sol;;;;;12-09-2019 04:45:57;
3;1;joao;00;00;;;;sem bairro;;;;;12-09-2019 05:38:13;
4;1;lua;00;00;;;;sem bairro;;;;;12-09-2019 06:11:15;
5;1;roberto;00;00;;;;sem bairro;;;;;12-09-2019 06:12:22;
6;1;joquina;00;00;;;;Monte Verde;;;;;12-09-2019 07:38:30;
7;1;luan silva;00;00;;;;sem bairro;;;;;12-09-2019 07:40:07;
8;1;manoel;00;00;;89898989;;sem bairro;asdasd;;;;12-09-2019 07:44:44;
9;1;joana;19;01;1954;;;Cidade Jardim;;;;;12-09-2019 07:48:03;
10;1;mariana;00;00;;;;sem bairro;;;;;12-09-2019 07:57:43;
11;1;agoradeucerto;00;00;;;;Morros;;;;;12-09-2019 08:01:46;
12;1;mais uma tentativa;00;00;;;;sem bairro;;;;;12-09-2019 08:43:19;
I'd like to have an output file as above, but without the empty lines.
I tried to see if the same would happen in console with the method System.out.println(), and it happened there too.
Looking in a text file editor, the Notepad, I noticed there are some LF mixed with CR LF in the end of lines.
I've reviewed the Contact class and all seems to be right.
So, what could I do to reach that result and avoid those empty lines, and why only the last line is in the correct place?
Thank you for your time.
EDIT 1 - The input method
Here is the input method. There are 2 ways to add the data into agendaDataArrayList. The first one is through reading a txt file (1st method) and the second one, through an input interface (2nd method).
1st method
public ArrayList<Contact> getAgendaDataArrayList(String path) {
try {
FileReader reader = new FileReader(path);
Scanner scanner1 = new Scanner(reader);
scanner1.useDelimiter("\r\n|\n");
int count = 0;
while(scanner1.hasNext()) {
scanner1.next();
count++;
}
System.out.println(count);
scanner1.close();
reader.close();
ArrayList<Contact> agendaDataArrayList = new ArrayList<Contact>();
FileReader reader2 = new FileReader(path);
Scanner scanner2 = new Scanner(reader2);
scanner2.useDelimiter(";");
for(int i=0; i<count; i++) {
Contact temp = new Contact();
temp.setIdAdress(scanner2.next()); //[0] id
temp.setContactType(scanner2.next()); //[1] type
temp.setName(scanner2.next()); //[2] name
temp.setBirthdayDay(scanner2.next()); //[3] birthdayDay
temp.setBirthdayMonth(scanner2.next()); //[4] birthdayMonth
temp.setBirthdayYear(scanner2.next()); //[5] birthdayYear
temp.setTel1(scanner2.next()); //[6] tel1
temp.setTel2(scanner2.next()); //[7] tel2
temp.setNeigborhood(scanner2.next()); //[8] neighborhood
temp.setAddress(scanner2.next()); //[9] address
temp.setCep(scanner2.next()); //[10] cep
temp.setEmail(scanner2.next()); //[11] email
temp.setOtherInformation(scanner2.next()); //[12] other information
temp.setCreationDate(scanner2.next()); //[13] creation date
agendaDataArrayList.add(temp);
}
scanner2.close();
reader2.close();
return agendaDataArrayList;
} catch (IOException e) {
e.printStackTrace();
ArrayList<Contact> agendaDataArrayList = new ArrayList<Contact>();
return agendaDataArrayList;
}
}
2nd method
public void saveActionButton() {
Date creationDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Contact newContact = new Contact();
newContact.setIdAdress(mainApp.getNextIdAddress());
if(typeChoiceBox.getValue()==null) {
newContact.setContactType("1");
} else {
newContact.setContactType(typeChoiceBox.getValue());
}
if(nameTextField.getText()==null) {
newContact.setName("sem nome");
} else {
newContact.setName(nameTextField.getText());
}
if(dayChoiceBox.getValue()==null) {
newContact.setBirthdayDay("00");
}else {
newContact.setBirthdayDay(dayChoiceBox.getValue());
}
if(monthChoiceBox.getValue()==null) {
newContact.setBirthdayMonth("00");
}else {
newContact.setBirthdayMonth(monthChoiceBox.getValue());
}
if(yearTextField.getText()==null) {
newContact.setBirthdayYear("0000");
}else {
newContact.setBirthdayYear(yearTextField.getText());
}
if(tel1TextField.getText()==null) {
newContact.setTel1("sem número");
}else {
newContact.setTel1(tel1TextField.getText());
}
if(tel2TextField.getText()==null) {
newContact.setTel2("sem número");
}else {
newContact.setTel2(tel2TextField.getText());
}
if(neighborhoodChoiceBox.getValue()==null) {
newContact.setNeigborhood("sem bairro");
} else {
newContact.setNeigborhood(neighborhoodChoiceBox.getValue());
}
if(addressTextField.getText()==null) {
newContact.setAddress("sem endereço");
} else {
newContact.setAddress(addressTextField.getText());
}
if(cepTextField.getText()==null) {
newContact.setCep("sem CEP");
}else {
newContact.setCep(cepTextField.getText());
}
if(emailTextField.getText()==null) {
newContact.setEmail("sem e-mail");
} else {
newContact.setEmail(emailTextField.getText());
}
if(otherInfoTextArea.getText()==null) {
newContact.setOtherInformation("sem mais informações");
}else {
newContact.setOtherInformation(otherInfoTextArea.getText());
}
newContact.setCreationDate(formatter.format(creationDate).toString());
mainApp.addContactToAgendaDataArrayList(newContact);
mainApp.refreshFullContentInMainLayout();
mainApp.saveFile();
Stage stage = (Stage) saveButton.getScene().getWindow();
stage.close();
}
}
Compare the first method output of the entries with id address 12 and the other ones that have new lines before them.
It is possible that some data are inserted on windows (therefore the CR LF whitespaces) and some on the unix system (which uses only LF). Anyway, it seems tha data itself contains new line marks, the PrinterWriter works as you would like.
A small test:
import java.util.ArrayList;
import java.io.*;
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
ArrayList<Contact> list = new ArrayList<>();
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
try {
File file = new File("output.txt");
PrintWriter p = new PrintWriter(file);
int count = list.size();
for (int i = 0; i < count; i++) {
Contact temp = list.get(i);
p.println(temp.getFavColour() + ";" + temp.getSurname() + ";" + temp.getName() + ";");
}
p.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static class Contact {
public String getName() {
return "John";
}
public String getSurname() {
return "Black";
}
public String getFavColour() {
return "red";
}
}
}

Storing Text file or folder in a header file and retrieve the data

How to Store Value stored in a folder/Text file in a header file and import it again to the program without the use of external memory or drives
This code gives me a incremented value each time when I run it and stores the value in a file. But I need to store the text file in the header itself rather than drives/external storage. So do we have any storage headers that I can use it instead of drives
class Test {
public static void main(String[] args) {
Test test1 = new Test();
test1.doMethod();
}
public int getCount() {
int count = 0;
try {
if (!new File("d:\\myCount.txt").exists())
return 1;
else {
BufferedReader br = new BufferedReader(new FileReader(new File("d:\\myCount.txt")));
String s = br.readLine();
count = Integer.parseInt(s);
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return count;
}
public void putCount(int count) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("d:\\myCount.txt")));
bw.write(Integer.toString(count));
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void doMethod() //Put Method//
{
int count = getCount();
if (count < 10000) {
NumberFormat nf = new DecimalFormat("0000");
System.out.println(" ID:" + nf.format(count));
count++;
putCount(count);
} else if (count >= 10000)
System.out.print("NO VACCANCY");
}
}

Search in a file for Specific sentences in a txt file in java

I have a TXT file with a multiple choice question and answer(like 150 question),this is the format:
what's your name?
a. danny
b. pedro
c. jose
d. mikey
I need to seek in the file and get the questions and the answer to show them in a UI interface.
For the moment, I can read and print the file, but I don't know how to get the sentence for separate.
Any suggestion?
The code:
import java.io.*;
import java.nio.file.Path;
public class fileManager {
public FileInputStream inputStream;
public InputStreamReader reader;
public File myfile;
public String question;
public String [] answer;
public fileManager(String myfile) {
this.myfile = new File(String.valueOf(myfile));
try {
inputStream = new FileInputStream(this.myfile );
try {
reader = new InputStreamReader(inputStream , "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void printFile(){
int indexChar = 1;
char concatination = '.';
int endFile = 0;
try {
endFile = inputStream.available();
} catch (IOException e) {
e.printStackTrace();
}
do {
try {
char mychar = (char)reader.read();
if (mychar == ((char)indexChar)){
if(concatination == (char)reader.read()){
do{
System.out.print((char)reader.read());
}while ((char)reader.read() == 'א');
}
}
endFile++;
} catch (IOException e) {
e.printStackTrace();
}
}while(endFile < 1000);
}
public void closeFile(){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
} //End function
public void getChar(){
}
public void getTheQuestion(){
int questionNum = 0;
int eof = 0;
int i =0;
String []file;
String question;
try {
eof = inputStream.available();
} catch (IOException e) {
e.printStackTrace();
}
for (;i == '1';){
try {
i = reader.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}//end getTheQuestion
//Getters and Setters
public FileInputStream getInputStream() {
return inputStream;
}
public void setInputStream(FileInputStream inputStream) {
this.inputStream = inputStream;
}
public File getMyfile() {
return myfile;
}
public void setMyfile(File myfile) {
this.myfile = myfile;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String[] getAnswer() {
return answer;
}
public void setAnswer(String[] answer) {
this.answer = answer;
}
}
You can accomplish it with regular expressions. Here I have written a program to help.
I have created Pattern's for questions and all four options and then fetched them.
File file = new File("myfile.txt");
Scanner sc = new Scanner(file);
Pattern questionPattern = Pattern.compile("(^(.+\\?)(?=(\\s+(a\\.\\s+.+)"
+ "\\s+b\\.\\s+.+\\s+c\\.\\s+.+\\s+d\\.\\s+.+)))", Pattern.CASE_INSENSITIVE);
Pattern optionAPattern = Pattern.compile("((?<=(.+\\?\\s))(a\\..+)(?=(\\sb\\..+$)))");
Pattern optionBPattern = Pattern.compile("((?<=(\\s))(b\\..+)(?=(\\sc\\..+$)))");
Pattern optionCPattern = Pattern.compile("((?<=(\\s))(c\\..+)(?=(\\sd\\..+$)))");
Pattern optionDPattern = Pattern.compile("((?<=(\\s))(d\\..+)(?=(\\s*$)))");
if (sc.hasNextLine()) {
String line = sc.nextLine();
Matcher question = questionPattern.matcher(line);
Matcher optionA = optionAPattern.matcher(line);
Matcher optionB = optionBPattern.matcher(line);
Matcher optionC = optionCPattern.matcher(line);
Matcher optionD = optionDPattern.matcher(line);
if(question.find()) System.out.println(question.group());
if(optionA.find()) System.out.println(optionA.group());
if(optionB.find()) System.out.println(optionB.group());
if(optionC.find()) System.out.println(optionC.group());
if(optionD.find()) System.out.println(optionD.group());
}
Output :
what's your name?
a. danny
b. pedro
c. jose
d. mikey
I think you are a beginner. Try learning regular expression to understand the code
I use the afzalex solution,
Scanner look at line, so I suppose my line start with the "index Letters"(Actually is in hebrew)so I understand its an answer, you can look at createPatterns(), and the question is not the answer so i left them, and I decide this will be in the end of the IF sentences, Where if is not empty enter to add question.
Here the code:
import com.sun.org.apache.xerces.internal.impl.xpath.regex.Match;
import java.io.*;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by aby on 11/9/14.
*/
public class fileManager {
public File myfile;
public Pattern myAnswerAlef;
public Pattern myAnswerBet;
public Pattern myAnswerGimel;
public Pattern myAnswerDalet;
public Scanner myscanner;
List<String> question = new ArrayList<String>();
List<String> answerAlef = new ArrayList<String>();
List<String> answerBet = new ArrayList<String>();
List<String> answerGimel = new ArrayList<String>();
List<String> answerDalet = new ArrayList<String>();
public fileManager(String myfile) {
this.myfile = new File(String.valueOf(myfile));
try {
myscanner = new Scanner(this.myfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
getAnswerQuestions();
}
public void closeFile(){
myscanner.close();
} //End function
public void createPatterns(){
myAnswerAlef = Pattern.compile("[א]+[.]");
myAnswerBet = Pattern.compile("[ב]+[.]");
myAnswerGimel = Pattern.compile("[ג]+[.]");
myAnswerDalet = Pattern.compile("[ד]+[.]");
}
public void getAnswerQuestions(){
createPatterns();
do {
String line = myscanner.nextLine();
if(line.length() != 1){
Matcher MatcherAnswerAlef = myAnswerAlef.matcher(line);
Matcher MatcherAnswerBet = myAnswerBet.matcher(line);
Matcher MatcherAnswerGimel = myAnswerGimel.matcher(line);
Matcher MatcherAnswerDalet = myAnswerDalet.matcher(line);
if (MatcherAnswerAlef.find()){
answerAlef.add(line);
}
else
if (MatcherAnswerBet.find()){
answerBet.add(line);
}
else
if (MatcherAnswerGimel.find()){
answerGimel.add(line);
}
else
if (MatcherAnswerDalet.find()){
answerDalet.add(line);
}
else
if (!line.isEmpty()){
question.add(line);
}
}
else{
continue;
}
}while (myscanner.hasNext());
}
}

File Structured Error [duplicate]

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.

Categories

Resources