EOFException using random access files - java

I'm using random access files to write a raf using an arrayList store. I do not know if it can be done, but I'm giving it a try because it is the best solution for me to create this application.
Here is the run-time error that I am getting:
Exception in thread "main" java.io.EOFException
at java.io.RandomAccessFile.readChar(Unknown Source)
at Student.read(Student.java:93)
at MainApp.start(MainApp.java:60)
at MainApp.main(MainApp.java:17)
And here is my code:
MainApp
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
public class MainApp
{
public static void main(String[] args) throws Exception
{
new MainApp().start();
}
public void start()throws Exception
{
StudentStore details = new StudentStore();
//Student a = new Student("Becky O'Brien", "DKIT26", "0876126944", "bexo#hotmail.com");
//details.print();
RandomAccessFile raf = new RandomAccessFile("ContactDetails.txt", "rw");
Student a = new Student("Becky O'Brien", "DKIT26", "0876126944", "bexo#hotmail.com");
Student b = new Student("Fabio Borini", "DKIT28", "0876136944", "fabioborini#gmail.com");
Student c = new Student("Gaston Ramirez", "DKIT29", "0419834501", "gramirez#webmail.com");
Student d = new Student("Luis Suarez", "DKIT7", "0868989878", "luissuarez#yahoo.com");
Student e = new Student("Andy Carroll", "DKIT9", "0853456788", "carroll123#hotmail.com");
details.add(a);
details.add(b);
details.add(c);
details.add(d);
details.add(e);
for (int i = 0; i < details.size(); i++)
{
//a.setStudentName(a[i]);
//a.setLastName(lnames[i]);
// a.setAddress(addresses[i]);
// a.setAge(ages[i]);
// a.setSalary(salaries[i]);
a.write(raf);
}
raf = new RandomAccessFile("employee.dat", "rw");
// er = new Student();
int numRecords = (int) raf.length() / details.size();
for (int i = 0; i < numRecords; i++) {
a.read(raf);
System.out.print(a.getStudentName() + " ");
System.out.print(a.getStudentId() + " ");
System.out.print(a.getStudentEmail() + " ");
System.out.print(a.getStudentTelephoneNumber() + " ");
}
raf.seek(0);
for (int i = 0; i < numRecords; i++)
{
a.read(raf);
raf.seek(raf.getFilePointer() - details.size());
a.write(raf);
raf.seek(raf.getFilePointer() - details.size());
a.read(raf);
}
System.out.print(a.getStudentName() + " ");
System.out.print(a.getStudentId() + " ");
System.out.print(a.getStudentEmail() + " ");
System.out.print(a.getStudentTelephoneNumber() + " ");
}
}
Student
import java.io.IOException;
import java.io.RandomAccessFile;
public class Student
{
//---------------------------------------------------------------------------
// Class Variables.
//---------------------------------------------------------------------------
private String studentName;
private String studentId;
private String studentTelephoneNumber;
private String studentEmail;
//---------------------------------------------------------------------------
// Constructor.
//---------------------------------------------------------------------------
public Student(String studentName, String studentId,String studentTelephoneNumber, String studentEmail)
{
this.studentName = studentName;
this.studentId = studentId;
this.studentTelephoneNumber = studentTelephoneNumber;
this.studentEmail = studentEmail;
}
//---------------------------------------------------------------------------
// Getters.
//---------------------------------------------------------------------------
public String getStudentName()
{
return studentName;
}
public String getStudentId()
{
return studentId;
}
public String getStudentTelephoneNumber()
{
return studentTelephoneNumber;
}
public String getStudentEmail()
{
return studentEmail;
}
//---------------------------------------------------------------------------
// Setters.
//---------------------------------------------------------------------------
public void setStudentName(String studentName)
{
this.studentName = studentName;
}
public void setStudentId(String studentId)
{
this.studentId = studentId;
}
public void setStudentTelephoneNumber(String studentTelephoneNumber)
{
this.studentTelephoneNumber = studentTelephoneNumber;
}
public void setStudentEmail(String studentEmail)
{
this.studentEmail = studentEmail;
}
//---------------------------------------------------------------------------
// toString.
//---------------------------------------------------------------------------
public String toString()
{
return "---------------------------Student--------------------------- " +
"\nStudent Name:" + studentName +
"\nStudent Id:"+ studentId +
"\nStudent Telephone Number:"+ studentTelephoneNumber +
"\nStudent Email:" + studentEmail;
}
void read(RandomAccessFile raf) throws IOException
{
char[] temp = new char[15];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
studentName = new String(temp);
temp = new char[15];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
studentId = new String(temp);
temp = new char[30];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
studentEmail = new String(temp);
temp = new char[30];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
studentTelephoneNumber = new String(temp);
temp = new char[30];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
}
void write(RandomAccessFile raf) throws IOException
{
StringBuffer sb;
if (studentName != null)
sb = new StringBuffer(studentName);
else
sb = new StringBuffer();
sb.setLength(15);
raf.writeChars(sb.toString());
if (studentId != null)
sb = new StringBuffer(studentId);
else
sb = new StringBuffer();
sb.setLength(15);
raf.writeChars(sb.toString());
if (studentEmail != null)
sb = new StringBuffer(studentEmail);
else
sb = new StringBuffer();
sb.setLength(30);
raf.writeChars(sb.toString());
if (studentTelephoneNumber != null)
sb = new StringBuffer(studentTelephoneNumber);
else
sb = new StringBuffer();
sb.setLength(30);
raf.writeChars(sb.toString());
}
}

You are reading beyond the end of the file. Reading data that isn't there.

The basic problem is that you are reading more data than you are writing.
You are reading 30 char at the end of each record which you didn't write. Given you discard them it appears you don't need to be doing this. I would delete the code which reads after studentTelephoneNumber

If load just one detail do you get the problem? I think your problem is that you are reading off the end of the file. Your read function which reads 15/30 characters seem dangerous because you may not have written that much. Why not read until you get a comma or some other separator? (eg tab)
It's this sort of thing that looks dangerous
char[] temp = new char[15];
for (int i = 0; i < temp.length; i++)
temp[i] = raf.readChar();
Where does the 15 come from?
Try and break it down with just one detail and bulid up from there. You should find the error. I would personally read until you find a particular separator.

Related

Import Data as Array from TXT File in Java

I want to import a data like this from .txt file using Java.
I want to import this as an Array. The class of data is like this:
class SolidStateDrive {
String brand;
String model;
int capacityInGB;
}
So if the array from txt file is hardcoded, that would be like this:
ssd[0].brand = Samsung;
ssd[1].brand = Adata;
ssd[0].model = Evo970;
ssd[1].model = SU650;
ssd[0].capacityInGB = 512;
ssd[1].capacityInGB 240;
The problem is, when i try to read the .txt file, it only can store 1 data from first line. If more than one, it will give error ArrayOutOfBound Exception.
Im using while loop so that as long as the nextLine is not null, it will loop. This is my code:
int n = 0;
SolidStateDrive[] ssd = new SolidStateDrive[n+1];
try {
BufferedReader br = new BufferedReader(new FileReader("SSD.txt"));
String line = null;
while((line = br.readLine()) != null) {
String tmp[] = line.split("\t");
ssd[n] = new SolidStateDrive();
ssd[n].brand = tmp[0];
ssd[n].model = tmp[1];
ssd[n].capacityInGB = Integer.parseInt(tmp[2]);
n++;
}
br.close();
} catch(IOException ex) {
ex.printStackTrace();
}
Update : i already tried this but doesnt work either
SolidStateDrive[] ssd = new SolidStateDrive[2];
For complete code in that file : pastebin
The problem is in splitting line String tmp[] = line.split("\t");.
Take line one from txt ssd[0].brand = Samsung; output of split is same as input ssd[0].brand = Samsung;.
while ((line = br.readLine()) != null) {
String tmp[] = line.split("\t");
ssd[n] = new SolidStateDrive();
ssd[n].brand = tmp[0];
ssd[n].model = tmp[1];
ssd[n].capacityInGB = Integer.parseInt(tmp[2]);
n++;
}
So the tmp[] will contain only tmp[0] = ssd[0].brand = Samsung;.
When you try to access tmp[1] you will get
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1.
The solution to your problem,
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ReadData {
public static void main(String[] str) {
readData();
}
public static void readData() {
List<SolidStateDrive> ssd = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("SSD.txt"))) {
ssd = br.lines().map(s-> {
String[] tmp = s.split("\\s+");
return new SolidStateDrive(tmp[0], tmp[1], Integer.parseInt(tmp[2]));
}).collect(Collectors.toList());
} catch (IOException ex) {
ex.printStackTrace();
}
ssd.stream().forEach(System.out::println);
}
}
class SolidStateDrive {
String brand;
String model;
int capacityInGB;
public SolidStateDrive(String brand, String model, int capacityInGB) {
super();
this.brand = brand;
this.model = model;
this.capacityInGB = capacityInGB;
}
#Override
public String toString() {
return "SolidStateDrive [brand=" + brand + ", model=" + model + ", capacityInGB=" + capacityInGB + "]";
}
}
The ArrayOutOfBounds exception occurs in the code you posted in pastebin; you have a for loop that loops n+1 times, which will always be 1 more than the number of SSDs in the array. This is the offending for loop:
for (int j=0; j<=n; j++) {
System.out.println(j+ "\t" +ssd[j].brand+ "\t" +ssd[j].model+ "\t" +ssd[j].capacityInGB);
}
To fix it, just change the <= to <, so the loop goes up to, but not including, n, since you started it at 0, not 1. It should look like this:
for (int j = 0; j < n; j++) {
System.out.println(j + "\t" + ssd[j].brand + "\t" + ssd[j].model + "\t" + ssd[j].capacityInGB);
}

How can I take the length from the text files in java?

I am new in java. Firstly, I'm sorry for my English. I wrote a code to merge two different txt files in the mergedFile.txt with determined data from the data1.txt and data2.txt. I create 5 different arrays to use them better but I cannot learn the length of words in the textfiles so arrays are using determined parameter. If I want to add another student, this codes don't work. Can you help me?
data1.txt
ID,Name,LastName,Department
12345,John,Samon,Computer Science
14524,David,Souza,Electric and Electronic
.
.
data2.txt
ID,Q1,Q2,Q3,Midterm,Final
12345,100,90,75,89,100
14524,80,70,65,15,90
.
margedFile.txt
ID,Name,Q_Average,Midterm,Final,Department
12345,John,88.3,89,100,Computer Science
14524,David,67.0,100,70,Electric and Electronic
This is ReadData Class
import java.io.FileInputStream;//import java.io library
import java.util.Scanner;//import scanner library
public class ReadData {
public static String[] Read(String filename,String filename2) {
Scanner scan = null;
Scanner scan1 = null;/
FileInputStream input1 = null;
FileInputStream input = null;
String[] result = new String[3];
try {
input = new FileInputStream(filename);
scan = new Scanner(input);
input1 = new FileInputStream(filename2);
scan1 = new Scanner(input1);
String[][] myArray = new String[4][4];
String[][] myArray1 = new String[4][6];
while(scan.hasNext() || scan1.hasNext()) {
for (int i = 0; i < myArray.length; i++) {
String[] split =
scan.nextLine().trim().split(",");
for (int j = 0; j < split.length; j++)
{
myArray[i][j] = split[j];
}
}
for (int i = 0; i < myArray1.length; i++) {
String[] split1 = scan1.nextLine().trim().split(",");
for (int j = 0; j < split1.length; j++) {
myArray1[i][j] = split1[j];
}
}
}
int[][] quiz = new int[3][3];
double[] average = new double[3];
int sum = 0;
double averagee = 0;
for (int i = 0; i < quiz.length; i++) {
for (int j = 0; j < quiz.length; j++) {
quiz[i][j] = Integer.parseInt(myArray1[i+1][j+1]);
sum += quiz[i][j];
}
averagee = sum/quiz.length;
average[i] = averagee;
sum = 0;
}
for (int i = 1; i < myArray1.length; i++) {
for (int j = 1; j < myArray1.length; j++) {
if(myArray[i][0].equalsIgnoreCase(myArray1[j][0])) {
result[i-1] = "\n" + myArray[i][0] + " "+ myArray[i][1] + " " + (average[j-1]) +" "+ myArray1[j][4] +" " + myArray1[j][5] + " "+ myArray[i][3];
//System.out.println(Arrays.deepToString(myArray[i]) + " " + Arrays.deepToString(myArray1[j]));
}
}
}
//System.out.println(Arrays.deepToString(quiz));
//System.out.println(Arrays.toString(average));
}
catch(Exception e) {
System.out.println(e);
}
return result;
}
}
This is WriteData class
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
public class WriteData extends ReadData {
void Write(String filename) {
PrintWriter writer = null;
FileOutputStream output = null;
try {
output = new FileOutputStream(filename);
writer = new PrintWriter(output);
writer.print("ID,Name,Q_Average,Midterm,Final,Department ");
writer.print(Arrays.toString(Read("data1.txt",
"data2.txt")));
writer.flush();
writer.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}

How do I create an Array or ArrayList with a looped, column of strings that contain integers?

I have tried so hard to find a solution to this problem! Here is my code:
import java.io.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class Weather {
public static void main(String[] args) throws IOException {
//Getting the file.
String fileName = "weather2013.txt";
//Lines!
String line;
//Creating arrayList object
ArrayList aList = new ArrayList();
try {
BufferedReader input = new BufferedReader(new FileReader(fileName));
while ((line = input.readLine()) != null) {
aList.add(line);
}
//Close the file
input.close();
} catch (FileNotFoundException ex) {
System.out.println("File not found!");
}
//Station ID Number:
String firstLine = aList.get(1).toString();
String stationIDStr = firstLine.substring(0, 6);
int StationID = Integer.parseInt(stationIDStr);
//System.out.println(StationID);
//WBAN ID Number:
String wbanIDstr = firstLine.substring(7, 12);
int wbanID = Integer.parseInt(wbanIDstr);
//System.out.println(wbanID);
//Year!
String yearStr = firstLine.substring(12, 18).trim();
int year = Integer.parseInt(yearStr);
//System.out.println(year);
//Remove line of text (not needed)
aList.remove(0);
//Fog days:
int fogDays = 0;
for (int i = 0; i < aList.size(); i++) {
String listString = aList.get(i).toString(); //iterate each readLINE -> String
String lastDigits = listString.substring(132, 137); //Each entry from 132-137 only
char fogIndicator = lastDigits.charAt(0);
if (fogIndicator == '1') {
fogDays++;
}
}
//System.out.println(fogDays);
//Maximum and minimum average temps
for (int i = 0; i < aList.size(); i++) {
String listString = aList.get(i).toString();
String averageTempDigits = listString.substring(24, 30).trim();
}
}
}
The specific part of the code where I am having trouble is the VERY last for loop.
Here's what's being outputted:
47.9
41.8
.
.
.
.
41.8
67.0
66.5
I would like to know how to get this column above into an Array or ArrayList?

Keep Getting java.lang.ArrayIndexOutOfBoundsException and Cannot Determine Why

Working on a program that will read input from a file (using the Declaration of Independence as a test) and write the number of ints, chars, strings, etc. into another new file. But I'm running into a problem with my array index being out of bounds. I've looked over my loops a dozen times now, but I can't figure out what could be causing the problem. Thanks in advance for any help =]
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class P5 {
static String arrayString[] = new String[100];
static int numberLines = 0;
static int numberWords = 0;
static int numberChars = 0;
static int numberUpper = 0;
static int numberLower = 0;
static int numberDigits = 0;
static int numSpaces = 0;
static int numberTabs = 0;
static int numberSpecial = 0;
private static void readFile(String inputFile) {
try{
Scanner fileScan = new Scanner(new File("Declaration.txt"));
while(fileScan.hasNext()){
arrayString[numberWords] = fileScan.next();
numberWords++;
}
while(fileScan.hasNextLine()){
numberLines++;
}
fileScan.close();
}
catch(IOException e){
}
}
private static void gatherStatistics(String sArray[]) {
for (int i = 0; i < sArray.length; i++){
String line = sArray[i];
numberChars += line.length();
for (int j = 0; j < line.length(); j++){
char c = line.charAt(j);
if(Character.isUpperCase(c))
numberUpper++;
else if(Character.isLowerCase(c))
numberLower++;
else if(Character.isDigit(c))
numberDigits++;
else if(Character.isSpaceChar(c))
numSpaces++;
else if(c == '\t')
numberTabs++;
else
numberSpecial++;
}
}
}
private static void writeFile(String outputFile) {
try{
PrintWriter fileOut = new PrintWriter(new File("Statistics.txt"));
fileOut.println("Number of Lines: " + numberLines);
fileOut.println("Number of Words: " + numberWords);
fileOut.println("Number of Lines: " + numberChars);
fileOut.println("Number of Lines: " + numberUpper);
fileOut.println("Number of Lines: " + numberLower);
fileOut.println("Number of Lines: " + numberDigits);
fileOut.println("Number of Lines: " + numSpaces);
fileOut.println("Number of Lines: " + numberTabs);
fileOut.println("Number of Lines: " + numberSpecial);
fileOut.close();
System.exit(1);
} catch (FileNotFoundException e){}
}
public static void main(String[] args) {
readFile(args[0]);
gatherStatistics(arrayString);
writeFile(args[1]);
System.exit(1);
}
}
You have read a file with more than 100 lines.
Instead of using array, use ArrayList
Change this line:
static String arrayString[] = new String[100];
to:
static ArrayList<String> arrayString = new ArrayList<String>();
Change this line:
private static void gatherStatistics(String sArray[]) {
to:
private static void gatherStatistics(ArrayList<String> sArray) {
Change this line:
arrayString[numberWords] = fileScan.next();
to
arrayString.add(fileScan.next());

How to sort a file by grade?

This is a complete program that sorts the file by ID. However, I would like to sort it by grade. I modified it several times but it doesn't seem to work. Could someone please direct me where to change the ID to grade. Also, do you think this code can be simplified or are there any other code simpler than this code.
Sorry for the bad indentation, this source code can also be found here.
student.txt file:
4 A 87 A
5 B 99 A+
1 C 75 A
2 D 55 C
3 E 68 B
source:
import java.io.*;
import java.util.*;
class ShowData implements Comparable {
int id;
String name;
int marks;
String grade;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setMarks(int marks) {
this.marks = marks;
}
public int getMarks() {
return marks;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getGrade() {
return grade;
}
public int compareTo(Object Student) throws ClassCastException {
if (!(Student instanceof ShowData))
throw new ClassCastException("Error");
int ide = ((ShowData) Student).getId();
return this.id - ide;
}
}
public class SortFile {
SortFile() {
int j = 0;
ShowData data[] = new ShowData[5];
try {
FileInputStream fstream = new FileInputStream("C:/student.txt");
// Use DataInputStream to read binary NOT text.
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
ArrayList list = new ArrayList();
while ((strLine = br.readLine()) != null) {
list.add(strLine);
}
Iterator itr;
for (itr = list.iterator(); itr.hasNext();) {
String str = itr.next().toString();
String[] splitSt = str.split(" ");
String id = "", name = "", marks = "", grade = "";
for (int i = 0; i < splitSt.length; i++) {
id = splitSt[0];
name = splitSt[1];
marks = splitSt[2];
grade = splitSt[3];
}
data[j] = new ShowData();
data[j].setId(Integer.parseInt(id));
data[j].setName(name);
data[j].setMarks(Integer.parseInt(marks));
data[j].setGrade(grade);
j++;
}
Arrays.sort(data);
File file = new File("C:/new.txt");
FileWriter fw = new FileWriter(file, true);
BufferedWriter out = new BufferedWriter(fw);
System.out.println("********Sorted by id********");
String strVal = "";
for (int i = 0; i < 5; i++) {
ShowData show = data[i];
int no = show.getId();
String name = show.getName();
int marks = show.getMarks();
String grade = show.getGrade();
System.out.println(no + " " + name + " " + marks + " " + grade);
String d = no + " " + name + " " + marks + " " + grade;
ArrayList al = new ArrayList();
al.add(d + "\n");
Iterator itr1 = al.iterator();
while (itr1.hasNext()) {
out.write(itr1.next().toString());
out.newLine();
}
}
out.close();
} catch (Exception e) {
}
}
public static void main(String[] args) {
SortFile data = new SortFile();
}
}
The compareTo() method is currently comparing the IDs, not the grades. Try compare the
marks instead.

Categories