How to handle ArrayIndexedBoundexception in Java - java

I have been trying to get a specific columns from a csv file say having 30 columns but i need only 3 columns entirely when i execute the following code only i get only one entire column data..how to get 3 column data at a time.when i run it prints only one column...when i try to print multiple column it shows error message like
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at ReadCVS.main(ReadCVS.java:19)
public static void main(String[] args) throws Exception {
String splitBy = ",";
BufferedReader br = new BufferedReader(new FileReader("txt.csv"));
String line = br.readLine();
while((line = br.readLine()) !=null){
String[] b = line.split(splitBy);
PrintWriter out = new PrintWriter(new FileWriter("new.csv",true));
out.println(b[0]);
out.close();
}
br.close();
}

The problem is probably is:
You have only one line in your, txt.csv file.
When you called br.readLine(); for the first time, that line is read from the file and stored in String line variable. But you ignored that line, and you've read again, in your while condition:
while((line = br.readLine()) !=null)
So maybe you have an empty line or empty string after that first line. Then the while condition is true, but an empty String is stored in line variable. So the b[] has no element and b[0] is out of the bound.
One solution is to change this line:
String line = br.readLine();
to
String line = null;
[EDIT]
So if you try to read a file like the one in mkyong's site (as you linked in your comment) and split the lines by "," and write them in a new file for example, you can use a code like the code below:
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("c:\\new.csv",true));
BufferedReader br = new BufferedReader(new FileReader("c:\\txt.csv"));
String splitBy = ",";
String line = null;
while((line = br.readLine()) !=null){
StringBuffer newLine = new StringBuffer();
String[] b = line.split(splitBy);
for (int i = 0; i<b.length; i++)
{
if(b[i] == null || b[i].trim().isEmpty())
continue;
newLine.append(b[i].trim() + ";");
}
out.write(newLine.toString());
out.newLine();
}
out.close();
br.close();
}
Also you should know that the following line opens the output file in appendable way(the second boolean parameter in the constructor):
BufferedWriter out = new BufferedWriter(new FileWriter("c:\\new.csv",true));
Also I assumed the contents of the source file is the same as in mkyong's site, somethimg like this:
"1.0.0.0",, , ,"1.0.0.255","16777216", , "16777471","AU" ,, "Australia"
"1.0.1.0" , ,, "1.0.3.255" ,, ,"16777472","16778239" , , "CN" , ,"China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"
Good Luck.

Related

reading input from file until specific word is read

i am writing a java program to read a file and print output to another string variable.which is working perfectly as intended using is code.
{
String key = "";
FileReader file = new FileReader("C:/Users/raju/Desktop/input.txt");
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
while (line != null) {
key += line;
line = reader.readLine();
}
System.out.println(key); //this prints contents of .txt file
}
this prints whole text in the file.But i want to only print the lines till word END is encountered in file.
example: if input.txt file contains following text : this test file END extra in
it should print only :
this test file
Just do a simple indexOf to see where it is and if it exists in the line. If the instance is found one option would be using substring to cut off everything up until the index of the keyword. For a bit more control though try using java regular expressions.
String key = "";
FileReader file = new FileReader("C:/Users/raju/Desktop/input.txt");
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
while ((line = reader.readLine()) != null && line.indexOf("Keyword to look for") == -1)
key += line;
System.out.println(key);
I am not sure why it needs to be any more complicated than this:
BufferedReader re = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String str = re.readLine();
if (str.equals("exit")) break;
// whatever other code.
}
You can do it in many ways. one of them is using indexOf method to specify the start index of "END" in input and then using subString method.
for more information, read documentation of String calss. HERE
This will work for your issue.
public static void main(String[] args) throws IOException {
String key = "";
FileReader file = new FileReader("/home/halil/khalil.txt");
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
while (line != null) {
key += line;
line = reader.readLine();
} String output = "";
if(key.contains("END")) {
output = key.split("END")[0];
System.out.println(output);
}
}
You have to change your logic to check if the line contains "END".
If END not found in a line, add the line to key stringin your program
If yes, split that line into word array, read the line till you encounter the word "END" and append it to your key string. Consider using Stringbuilder for key.
while (line != null) {
line = reader.readLine();
if(!line.contains("END")){
key += line;
}else{
//Note that you can use split logic like below, or use java substring
String[] words = line.split("");
for(String s : words){
if(s.equals("END")){
return key;
}
key += s;
}
}
}

How to remove the duplicate string?

In my code I have two files in my drive those two files have some text and I want to display those string in the console and also remove the repeated string and display the repeated string once rather than displaying it twice.
Code:
public class read {
public static void main(String[] args) {
try{
File file = new File("D:\\file1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while((line = br.readLine()) != null){
stringBuffer.append(line);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file1:");
String first = stringBuffer.toString();
System.out.println(first);
File file1 = new File("D:\\file2.txt");
FileReader fileReader1 = new FileReader(file1);
BufferedReader br1 = new BufferedReader(fileReader1);
StringBuffer stringBuffer1 = new StringBuffer();
String line1;
while((line1 = br1.readLine()) != null){
stringBuffer1.append(line1);
stringBuffer1.append("\n");
}
fileReader1.close();
System.out.println("Contents of file2:");
String second = stringBuffer1.toString();
System.out.println(second);
System.out.println("answer:");
System.out.println(first+second);
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Output is:
answer:
hi hello
how are you
hi ya
i am fine
But I want to compare both the strings and if the same string repeated then that string should be displayed once.
Output I expect is like this:
answer:
hi hello
how are you
ya
i am fine
Where the "hi" is found in both the strings so that I need to delete the one duplicate string.
How can I do that please help.
Thanks in advance.
You can pass your lines through this method to parse out duplicate words:
// store unique previous words
static Set<String> words = new HashSet<>();
static String removeDuplicateWords(String line) {
StringJoiner sj = new StringJoiner(" ");
// split on whitespace to get distinct words
for (String word : line.split("\\s+")) {
// try to add word to the set
if (words.add(word)) {
// if the word was added (=not seen before), append to the result
sj.add(word);
}
}
return sj.toString();
}

read from file and write some parts in another file

I have to read from a text file and format the input. I'm new to java reading from files, and I don't know how to work with just some parts of what I read
Here is the initial file: http://pastebin.com/D0paWtAd
And I have to write in another file the following output:
Average,Joe,44,31,18,12,9,10
I've managed just to take everything from the file and print it to output. I would need help just in taking the output I need and print it to the screen. Any help is appreciated.
This is what I wrote up to now:
public class FileParsing {
public static String
read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\Bogdi\\Desktop\\example.txt"));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) sb.append(s + "\n");
in.close();
return sb.toString();
}
If your goal is to do the specified output in another file you don't need to first get the content of your file in a StringBuilder before processing it, you can append the processed datas directly in a StringBuilder then you can write the result in a file. Here is an example that would work for the given file but you may have to modify it if the keys change in the future:
The following method will correctly process the datas from your file
public static String read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) {
String[] split1 = s.split("=");
if (split1[0].equals("name")) {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
sb.append(tokenizer.nextToken());
sb.append(",");
sb.append(tokenizer.nextToken());
sb.append(",");
} else if (split1[0].equals("index")) {
sb.append(split1[1] + ",");
} else if (split1[0].equals("FBid")) {
sb.append(split1[1]);
} else {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
String wasted = tokenizer.nextToken();
sb.append(tokenizer.nextToken() + ",");
}
}
in.close();
return sb.toString();
}
The next method will read any string to a file
public static void writeStringToFile(String string, String filePath) throws IOException {
BufferedWriter writer = new BufferedWriter(
new FileWriter(
new File(filePath)
)
);
writer.write(string);
writer.newLine();
writer.flush();
writer.close();
}
And here is a simple tests (File1.txt contains the datas from the file you shared on paste bin and I write them in another file)
public static void main(String[] args) throws Exception {
String datas = read("C:\\Tests\\File1.txt");
System.out.println(datas);
writeStringToFile(datas, "C:\\Tests\\FileOuput.txt" );
}
It will produce the exact output that you are expecting
[EDIT] #idk, apparently you have an exception executing my example, while it is working fine for me. That could only mean there is an error at data level. Here is the data sample that I used (and I believe I exactly copy the datas you shared)
And here is the result:
Good to know you are using "StringBuilder" component instead being concatenating your String values, way to go :).
More than knowledge on the Java.IO API to work with files, you will need some logic to get the results you expect. Here I came with an approach that could help you, not perfect, but can point you on how to face this problem.
//Reference to your file
String myFilePath = "c:/dev/myFile.txt";
File myFile = new File(myFilePath);
//Create a buffered reader, which is a good start
BufferedReader breader = new BufferedReader(new FileReader(myFile));
//Define this variable called line that will evaluate each line of our file
String line = null;
//I will use a StringBuilder to append the information I need
StringBuilder appender = new StringBuilder();
while ((line = breader.readLine()) != null) {
//First, I will obtain the characters after "equals" sign
String afterEquals = line.substring(line.indexOf("=") + 1, line.length());
//Then, if it contains digits...
if (afterEquals.matches(".*\\d+.*")) {
//I will just get the digits from the line
afterEquals = afterEquals.replaceAll("\\D+","");
}
//Finally, append the contents
appender.append(afterEquals);
appender.append(",");//This is the comma you want to include
}
//I will delete the last comma
appender.deleteCharAt(appender.length() - 1);
//Close the reader...
breader.close();
//Then create a process to write the content
BufferedWriter myWriter = new BufferedWriter(new FileWriter(new File("myResultFile.txt")));
//Write the full contents I get from my appender :)
myWriter.write(appender.toString());
//Close the writer
myWriter.close();
}
Hope this can help you. Happy coding!

Readline() reads only first line

I need to read a text file and split using a common text in the lines, and print a part of the split text. This works fine but only does this for the first line in the text.
However, if I print lines without the split part, it prints correctly. Please what am I doing wrong?
File sample: (I want to split by "words")
Line 1 This text is of length: 7 words. I need to learn how to program.
Line 2 Now we have text of length: 3 words. No matter what the words are, I must program
FileInputStream fis = new FileInputStream(fin);
//Construct BufferedReader from InputStreamReader
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
ArrayList<String> txt1 = new ArrayList<>();
while ((line = br.readLine()) != null) {
String[] pair = line.split("words");
txt1.add(pair[1]);
System.out.println(txt1);
//System.out.println(line);
}
br.close();
Given the following unit test simulating the input of a file via a StringInputStream:
#Test
public void test() throws IOException
{
String fileContent = "This text is of length: 7 words.\r\nI need to learn how to program and one day.";
StringInputStream stream = new StringInputStream(fileContent);
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line = null;
ArrayList<String> txt1 = new ArrayList<>();
while ((line = br.readLine()) != null) {
String[] pair = line.split("words");
txt1.add(pair[1]);
System.out.println(txt1);
//System.out.println(line);
}
}
The first line will be split into
"This text is of length: 7 " and
"."
Since you put item [1] into the array list, it'll just contain a single dot.
The second line will be split into
"I need to learn how to program and one day."
only. There is no second item, so accessing [1] results in a ArrayIndexOutOfBoundsException.

how to read from a huge file and write to a new file by java

What I am doing is to read one file line by line, format every line, then write to a new file. But the problem is that the file is huge, nearly 178 MB. But always getting error message: IO console updater error, java heap space. Here is my code:
public class fileFormat {
public static void main(String[] args) throws IOException{
String strLine;
FileInputStream fstream = new FileInputStream("train_final.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fstream));
BufferedWriter writer = new BufferedWriter(new FileWriter("newOUTPUT.txt"));
while((strLine = reader.readLine()) != null){
List<String> numberBox = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(strLine);
while(st.hasMoreTokens()){
numberBox.add(st.nextToken());
}
for (int i=1; i< numberBox.size(); i++){
String head = numberBox.get(0);
String tail = numberBox.get(i);
String line = head + " "+tail ;
System.out.println(line);
writer.write(line);
writer.newLine();
}
numberBox.clear();
}
reader.close();
writer.close();
}
}
How can I avoid this error message? Moreover, I have set the VM preference: -xms1024m
Remove the line
System.out.println(line);
This is a workaround the fialing console updater, which otherwise runs out of memory.
The program looks okay. I suspect the problem is that you run this inside of Eclipse, and System.out is collected by Eclipse in memory (to be displayed in that Console window).
System.out.println(line);
Try to run it outside of Eclipse, change Eclipse settings to pipe System.out somewhere, or remove the line.
This part of the code:
for (int i=1; i< numberBox.size(); i++){
String head = numberBox.get(0);
String tail = numberBox.get(i);
String line = head + " "+tail ;
System.out.println(line);
writer.write(line);
writer.newLine();
}
Can be translated to:
String head = numberBox.get(0);
for (int i=1; i< numberBox.size(); i++){
String tail = numberBox.get(i);
System.out.print(head);
System.out.print(" ");
System.out.println(tail);
writer.write(head);
writer.write(" ");
writer.write(tail);
writer.newLine();
}
This may add a little code duplication but it avoids creating a lot of objects.
Also there if you merge this for loop with the loop contructing the numberBox, you won't need numberBox structure at all.
If you read whole file the heap memory will occupy so better option in to read the file in chuck. See my below code. It will start reading from the offset given in argument and will return the end offset . You need to pass number of lines to be read.
Please remember: You can use any collection to store these read lines and clear the collection before calling this method to read next chunk.
FileInputStream fis = new FileInputStream(file);
InputStreamReader streamReader = new InputStreamReader(fis, "UTF-8");
LineNumberReader reader = new LineNumberReader(streamReader);
//call this below method recursively until the file does not reaches to the end
public int getParsedLines(LineNumberReader reader, int iLineNumber_Start, int iNumberOfLinesToBeRead) {
int iLineNumber_End = 0;
int iReadUptoLines = iLineNumber_Start + iNumberOfLinesToBeRead;
try {
reader.mark(iLineNumber_Start);
reader.setLineNumber(iLineNumber_Start);
do {
String str = reader.readLine();
if (str == null) {
break;
}
// your code
iLineNumber_End = reader.getLineNumber();
} while (iLineNumber_End != iReadUptoLines);
} catch (Exception ex) {
// exception handling
}
return iLineNumber_End;
}

Categories

Resources