java substring within filreader while - java

Can't find any help on how to do this:
I can't use .substring in the Filreader's while, it throws an exception after reading the first line.
String line = "";
BufferedReader in = new BufferedReader( new FileReader(f) );
LineNumberReader lnr = new LineNumberReader(in);
while ((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + " : " + line.substring(1, 7) +"!");
}
in.close();
lnr.close();

Glad that you have already found the answer to your problem, additionally I would like to suggest adding a range check when calling substring (at least in cases where a variable length of line is expected)
if (line.length() > 7) {
System.out.println(lnr.getLineNumber() + " : " + line.substring(1, 7) +"!");
}
else {
System.err.println("Unexpected line, minimum expected length=7 chars");
}

Related

I have a problem in file handling in java

any help will be appreciated.
print some details about fines on it, but the code is not giving me an output.
my code is :
class BookLib{
String userName ;
String bookName;
int noOfDays;
int fine;
#Override
public String toString() {
return "BookLib{" +
"userName='" + userName + '\'' +
", bookName='" + bookName + '\'' +
", noOfDays=" + noOfDays + '}';
}
}
class Library{
List<BookLib> books = new ArrayList<>();
void readDetails() throws IOException{
FileReader fr = new FileReader("fineDetails.txt");
BufferedReader br = new BufferedReader(fr);
String thisLine;
List<String> lines = new ArrayList<>();
while ((thisLine = br.readLine()) != null) {
lines.add(thisLine);
}
for(String readLine: lines){
StringTokenizer stringTokenizer = new StringTokenizer(readLine, ",");
BookLib tempBook = new BookLib();
tempBook.userName = stringTokenizer.nextToken().trim();
tempBook.bookName = stringTokenizer.nextToken().trim();
tempBook.noOfDays = Integer.parseInt(stringTokenizer.nextToken().trim());
System.out.println("BookLib = " + tempBook);
books.add(tempBook)
}
br.close();
fr.close();
}
I Hope, Above code, is helping you for handling NumberFormatException and future ArrayIndexOutOfBoundException handling. you may also use try-catch {} for handling these errors.
The problem is that you can't parse the String "25 " to an Integer because of the whitespace.
You can remove the whitespace using the trim method of String like this:
//...
book[i].userName = stringTokenizer.nextToken();
book[i].bookName = stringTokenizer.nextToken();
book[i].noOfDays = Integer.parseInt(stringTokenizer.nextToken().trim()); // trim here
//...
I think there is another problem that didn't cause any errors yet, because the NumberFormatException occured earlier: You do close the readers br and fr in the for loop, but they will still be used there. You should move the lines br.close() and fr.close() down to the end of the method.

Java - NumberFormatException at linear search

I am having this issue with the NumberFormatException in my program. Basically, I am asked to read a .csv file separated by ; and it looks like this:
// Column Explanation (not in .csv file)
id; Summary; Number; Employee1; Employee2; ....... Employee7;
"1";"Sony";"1600";"Markos";"Nikos";"Antonis";"Nikolas";"Vaggelis";"Markos";"Thanasis";
"2";"HP";"1000";"Marios";"Dimitra";"Nikolia";"Spiros";"Thomas";"Kostas";"Manolis";
"3";"Dell";"1100";"Antonis";"Aggelos";"Baggelis";"Nikos";"Kuriakos";"Panagiotis";"Rafail";
"4";"Acer";"2000";"Marina";"Aggelos";"Spiros";"Marinos";"Xristos";"Antreas";"Basilis";
What I have already done is create a String 2-d array or the .csv file called temp_arr and I am asked to write a method that will run a linear search by id and return that company. So here is the thing.
At first, I thought I should convert the input key from int -> String since my temp_arr is a String and compares the strings (which at that time they would be int but read as Strings) using temp_arr[value][value2].equals(string_key). But I had a NullPointerException.
Then I thought I should better convert my Id's from the temp_arr from String -> Int and then compare with the integer key using == operand. This action returned me a NumberFormatException.
The process is this:
System.out.println("Enter id :");
Scanner input = new Scanner(System.in);
int item = input.nextInt(); // read the key which is an Integer
int id_int; // temp_arr is String and item is int, must convert ids from String -> int
for (int i = 0; i < temp_arr.length; i++)
{
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
if (id_int == item) // If the Array's Id's are == item
{
System.out.println(item+" is present at location " + (i+1) );
break;
}
if (i == temp_arr.length)
System.out.println(item + " does not exist");
}
My error appears at line 7 and I do not know why.
Read File process:
String csvFile = "sam.csv"; // .csv file to be placed in the project file!
BufferedReader br = null; // ini
String line = "",cvsSplitBy = ";"; // columns asked to be split by ";"
String[] arr = null;
String[][] temp_arr = new String[1000][10];
int temp = 0;
try
{
br = new BufferedReader(new FileReader(csvFile)); //start reading the file
while ((line = br.readLine()) != null) // while the line has words
{
arr = line.split(cvsSplitBy); // creating the array
System.out.println(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\t" + arr[3] + "\t" + arr[4] + "\t" + arr[5] + "\t" + arr[6] + "\t" + arr[7] + "\t" + arr[8] + "\t" + arr[9] );
for (int i = 0; i<=9; i++)
{
temp_arr[temp][i] = arr[i]; // temp_arr represents (is a copy of) the .csv file
}
temp++;
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (br != null)
{
try
{
br.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println("Done!\n");
Output (Image) :
Line 106 which is causing the issue is :
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
Your issue is that your Integer.parseInt() is trying to parse a "2" WITH QUOTATION MARKS. That's the problem.
A quick solution would be to replace this line:
temp_arr[temp][i] = arr[i];
To this:
temp_arr[temp][i] = arr[i].replaceAll("\"", "");
Anyway, I'd like to suggest using a different data structure for your case, because I've done something like this before for a client. Have you ever heard of HashMaps? You can do something like a HashMap with an int key and String[] values to store your data in, and the key can be your id_int. Maybe you can try this implementation next time. It's a lot more elegant.
Hope I was able to help!
Cheers,
Justin
Would help if you also posted some of your data file and how you are reading it in.
But, my guess from what is presented is if you add System.out.println(temp_arr[i][0]) prior to the 7th line or run this code through a debugger you will see that temp_arr[i][0] is not an integer value as that is what the error is telling you.

Is it possible to write a few StringArray values into one String?

I'm trying to write a part of an String array into a String but I just stuck at a problem.
The disposal of the value of line is always like this: "status.test.status.close.name = Closed".
The only static of this value is "status." and ".name". I just want to get the part between "status." and ".name". With the code below I get this result: "status.test.status.close". My question now is, is it possible to delete parts of an array, for example: technicalNames.delete["status."];? Or does anyone has another hint how to realize it?
public void setTechnicalName(File javaFile) throws IOException {
if(javaFile.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(javaFile));
String line = null;
while((line = reader.readLine()) != null)
if (line.contains("In approval") || line.contains("In Approval") || line.contains("In review") || line.contains("In Review") || line.contains("Closed")){
System.out.println(line);
String[] technicalNames = line.split(".name");
String technicalName = technicalNames[0];
System.out.println(technicalName);
}
reader.close();
}
}
That is the .xml file i read out:
status.test.status.close.name = Closed
status.test.status.in.approval.name = In approval
status.test.status.in.review.name = In review
test.field.approver1 = Approver
test.field.lookupworkflow =
test.field.temp = temp
Thanks in advance!
I am assuming that you are interested in parts between status and .name. You can try this way of doing it.
public static void setTechnicalName(File javaFile) throws IOException {
if(javaFile.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(javaFile));
String line = null;
int statusOffet = "status.".length();
while((line = reader.readLine()) != null){
int indexOfStatus = line.indexOf("status");
int indexOfName = line.lastIndexOf(".name");
boolean isReqLine = line.contains("In approval")
|| line.contains("In Approval")
|| line.contains("In review")
|| line.contains("In Review")
|| line.contains("Closed");
if(isReqLine && indexOfStatus != -1 && indexOfName != -1){
System.out.println(line);
String stage = line.substring(indexOfStatus + statusOffet, indexOfName);
System.out.println(stage);
}
}
reader.close();
}
}
EDIT : as per comment to match format, I have included "." when calculating offset and used indexOf
When you want to split your given line into parts, you can do it similar to
final String string = "status.test.status.close.name = Closed";
final String[] split = string.substring(0, string.indexOf("=")).split("\\.");
System.out.println("split = [" + split[0] + ", " + split[1] + ", " + split[2] + ", " + split[3] + ", " + split[4] + "]"); // split = [status, test, status, close, name ]
and pick the appropriate values out of split afterwards.
Well, you have status defined twice. So assuming you are referring to the first status, and the desired result is to print out test.status.close you could do this if you knew that indexes 0 and n-1 would be not of interest:
StringBuilder builder = new StringBuilder();
String[] parts = line.split(".name")[0].split("\\.");
for(int i = 1; i < parts.length - 1; i++){
builder.append(parts[i]);
if(i < parts.length - 1){
builder.append(".");
}
System.out.println(builder.toString())

Java StringTokenizer running out of bounds with .CSV file

I am trying to read a simple .CSV file and create a 2D array of Strings. Here is the array:
1,1,1,1,1,1
2,2,2,2,2,2
3,3,3,3,3,3
4,4,4,4,4,4
My code is supposed to find six columns and four rows, but it stops after the third column and moves on to the next row and I cannot figure out why this is happening.
In addition to this, it returns an out of bounds exception even though it quits early.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
Here is the code and it is followed by the output.
public String[][] ascToStringArray(String ascFileIn) {
String directory ="c:\\data\\"; // "\" is an illegal character
String[][] numbers= new String[4][6]; // 4 rows 6 columns
try{
BufferedReader Br = new BufferedReader(new FileReader(directory + ascFileIn));
String line;
int row = 0;
int col = 0;
//read each line of text file
while((line = Br.readLine()) != null)
{
StringTokenizer st = new StringTokenizer(line,",");
//Populating Columns
while (st.hasMoreTokens())
{
//get next token and store it in the array
numbers[row][col] = st.nextToken();
System.out.println(row + " " + col + " = " + st.nextToken());
col++;
}
row++;
}
//close the file
Br.close();
return numbers;
}
catch(IOException exc) {
System.out.println("Error reading file.");
return numbers;
}
}
Here is the output:
0 0 = 1
0 1 = 1
0 2 = 1
1 3 = 2
1 4 = 2
1 5 = 2
If anyone can figure out why it is quitting early and throwing me an out of bounds error no matter how large I make the array I would really appreciate it.
You are using nextToken twice.
numbers[row][col] = st.nextToken();<-1---
System.out.println(row + " " + col + " = " + st.nextToken());<--2--Skips element
But using only one value so in one row only three element of line will be added.
Reason of Exception
You are not resetting the col=0 after the execution of inner while loop which leads to ArrayIndexOutOfBound for col=6 as col size in array is 6 means 0 to 5 so will throw exception when col=6.
Firstly the system.out.println inside the inner while loop consumes a token.. Second on entring the inner while loop you should reset the cols files. to zero.
public String[][] ascToStringArray(String ascFileIn) {
String directory = "c:\\data\\"; // "\" is an illegal character
String[][] numbers = new String[4][6]; // 4 rows 6 columns
try {
BufferedReader Br = new BufferedReader(new FileReader(directory + ascFileIn));
String line;
int row = 0;
int col = 0;
// read each line of text file
while ((line = Br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",");
col = 0;
// Populating Columns
while (st.hasMoreTokens()) {
// get next token and store it in the array
numbers[row][col] = st.nextToken();
col++;
}
row++;
}
// close the file
Br.close();
return numbers;
} catch (IOException exc) {
System.out.println("Error reading file.");
return numbers;
}
}
It's because you are calling st.nextToken() twice, swallowing an extra token in your System.out.println.
Instead, first save it into a String:
String token = st.nextToken();
then you can use the same String in your print and for the array.
http://msdn.microsoft.com/fr-fr/library/aa989865(v=vs.80).aspx
StringTokenizer.nextToken () : Gets the next token in the string
during parsing.
numbers[row][col] = st.nextToken();
System.out.println(row + " " + col + " = " + st.nextToken());
You go through your tokens without using them !

Java Log File Reader, charAt() String index out of range

I have a problem.
I want to make a programm, that takes a Log File and parse it line for line.
A Log looks like this:
"2014-02-14 14:26:37,836 INFO [org.jboss.msc] (main) JBoss MSC
version 1.0.4.GA-redhat-1"
My code:
public static void main(String[] args) throws InterruptedException {
try
{
String sCurrentLine;
BufferedReader br = new BufferedReader(new FileReader("C:\\server.log"));
while ((sCurrentLine = br.readLine()) != null) {
String datetime = "";
String level = "";
String category = "";
String message = "";
String output = "";
if(sCurrentLine.length()<1){
}
else{
if (sCurrentLine.charAt(4)=='-' && sCurrentLine.charAt(7)=='-' && sCurrentLine.charAt(13)==':' && sCurrentLine.charAt(16)==':'){
String[] leerzeichen = sCurrentLine.split(" ");
String[] leerzeichenz = sCurrentLine.split(" ");
datetime = leerzeichen[0] + " " + leerzeichen[1];
level = leerzeichen[2];
category = leerzeichen[4];
int arraylength = leerzeichen.length;
for (int l=5; l<arraylength; l++){
message = message.concat(leerzeichen[l] + " ");
}
output = datetime + level + category + message;
} else {
message = message.concat(sCurrentLine);
output += message;
}
}
System.out.println(output);
}
} catch (IOException e) {
e.printStackTrace();
}
}
The Program looks, if the beginning of the Line looks like this: 0000-00-00 00:00:00
If not, the Line is only a message in connection with the line before.
But I always get the Error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:658)
at javaapplication5.JavaApplication5.main(JavaApplication5.java:38)
But he reads some lines of the log. But not until the end of the log.
Can you help me? sorry for my English.
You have problem in line:
if (sCurrentLine.charAt(4)=='-' && sCurrentLine.charAt(7)=='-' && sCurrentLine.charAt(13)==':' && sCurrentLine.charAt(16)==':'){
You cannot assume that the line have at least 4, 7 or more characters.
Try changing it to this:
if (sCurrentLine.length() >= 16 && sCurrentLine.charAt(4)=='-' && sCurrentLine.charAt(7)=='-' && sCurrentLine.charAt(13)==':' && sCurrentLine.charAt(16)==':'){
The cause of error is quite straight forward; you first check if string has length > 1, and then directly ask for char at index 4 -- which is no guarantee to exists since all you know is thats length > 1.
Hence, add proper checking before trying to access char at index 4, and most of all, as said in comment by #VusP, add some print/debugging of the read string before trying to parse it.

Categories