BufferedRead stuck in infinite loop - java

I am doing a class project that is supposed to read a .txt file and have the program also replace some text. But after I run the code it just constantly runs in a loop and only reading one line of the text. Not really sure what I did wrong but I think it's the reader part of my code.
public class FormLetter
{
final static int MAX_LINES = 20;
final static int NUM_INSERTIONS = 4;
String[] formLetter = new String[MAX_LINES];
int lines = 0;
public static void main(String[] args)
{
FormLetter letter1 = new FormLetter("formLetter..txt");
FormLetter letter2 = new FormLetter("longLetter.txt");
FormLetter letter3 = new FormLetter("formLetter.txt");
letter3.generateLetter("insertions.txt");
}
public FormLetter(String formFileName)
{
Scanner formFileIn;
String line;
Path file = Paths.get("H:\\Eclipse\\Programming Project 1\\formLetter.txt");
InputStream input = null;
try
{
formFileIn = new Scanner(new FileReader(formFileName));
while (lines < MAX_LINES && formFileIn.hasNextLine())
{
input = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
Charset.defaultCharset();
line = reader.readLine();
System.out.println(line);
}
if (formFileIn.hasNextLine())
{
System.out.println("File " + formFileName + " is too large to process.\n");
}
}
catch(FileNotFoundException fnfe)
{
System.out.println("Cannot open " + formFileName + "\n");
}
catch(IOException ioe)
{
System.out.println("Error reading from file" + formFileName);
}
}

As mentioned in the comments I was using two readers by mistake causing an infinite loop. I removed the second reader and during my loop now only put to output the next line from the file.
import java.util.Scanner;
import java.io.*;
import java.nio.file.*;
import java.nio.charset.*;
import java.nio.file.StandardOpenOption;
public class FormLetter
{
final static int MAX_LINES = 20;
final static int NUM_INSERTIONS = 4;
String[] formLetter = new String[MAX_LINES];
int lines = 0;
public static void main(String[] args)
{
FormLetter letter1 = new FormLetter("formLetter..txt");
FormLetter letter2 = new FormLetter("longLetter.txt");
FormLetter letter3 = new FormLetter("formLetter.txt");
letter3.generateLetter("insertions.txt");
}
public FormLetter(String formFileName)
{
Scanner formFileIn;
String line;
try
{
formFileIn = new Scanner(new FileReader("H:\\Eclipse\\Programming Project 1\\formLetter.txt"));
while (lines < MAX_LINES && formFileIn.hasNextLine())
{
System.out.println(formFileIn.next());
}
if (formFileIn.hasNextLine())
{
System.out.println("File " + formFileName + " is too large to process.\n");
}
}
catch(FileNotFoundException fnfe)
{
System.out.println("Cannot open " + formFileName + "\n");
}
catch(IOException ioe)
{
System.out.println("Error reading from file" + formFileName);
}
}

Related

Java error: method readFile() in class cannot be applied to given types

im a first year computer science student learning java and im trying to read a csv file line by line and convert each row to an object, then create an array out of these objects with each element separated by a comma ",". Program keeps returning unusual error: method readFile() in class cannot be applied to given types. im not sure what to do.
main class:
import java.io.*;
import java.util.*;
public class FlightOperations
{
static String fileName = "LaxData.csv";
public static void main(String[] args)
{
// Parsing a CSV file into Scanner class constructor
Scanner sc = new Scanner(System.in);
int fileLength = 0;
fileLength = getFileCount(fileName);
int again = 0;
Date[] LAXarray = new Date[fileLength];
LAXarray = readFile(fileName, fileLength);
menu(LAXarray, sc);
do
{
try
{
System.out.println("\n\nRun program? (1)YES (2)NO");
again = sc.nextInt();
if(again == 1)
{
menu(LAXarray, sc);
}
else
{
System.exit(1);
}
}
catch (InputMismatchException exception)
{
System.out.println("\nInvalid input");
sc.next();
}
}
while (again != 1 || again != 2);
sc.close(); // closes the scanner
}
readFile class:
public static Date[] readFile(String fileName)
{
FileInputStream fileStream = null;
InputStreamReader Read;
BuffferedReader bufRead;
/* int fileLength = getFileLength(fileName); */
String line;
Date[] LAXarray = new Date[getFileCOunt(fileLength)];
int LAXIndex = 0;
try
{
fileStream = new FileInputStream(fileName);
Read = new InputStreamReader(fileStream);
bufRead = new BufferedReader(Read);
line = bufRead.readLine();
for(int i = 1; i < fileLength; i++)
{
line = bufRead.readLine();
LAXarray[i] = processLine(line);
}
}
catch(IOException errorDetails)
{
if(fileStream != null)
{
try
{
fileStream.close();
}
catch(IOException ex2)
{
}
}
System.out.println("Error in fileProcessing: " + errorDetails.getMessage());
}
return LAXarray;
}

Reading a text file from implementation

I am trying to create an implementation that reads a file that the user has typed and submitted. The code for that is located in the SetTester class (shown below). In my implementation I already have an array declared called String[] myArray = new String [] {}; to hold the data from the file. How would I be able to take the file that is being called in the tester class and put it into that array?
public class SetTester
{
public static void main(String [] args) {
StringSet words = new MyStringSet();
Scanner file = null;
FileInputStream fs = null;
String input;
Scanner kb = new Scanner(System.in);
int wordCt = 0;
boolean ok = false;
while (!ok)
{
System.out.print("Enter name of input file: ");
input = kb.nextLine();
try
{
fs = new FileInputStream(input);
ok = true;
}
catch (FileNotFoundException e)
{
System.out.println(input + " is not a valid file. Try again.");
}
}
file = new Scanner(fs);
while (file.hasNext())
{
input = file.next();
words.insert(input);
System.out.println("Current capacity: " + words.getCapacity());
wordCt++;
}
System.out.println("There were " + wordCt + " words in the file");
System.out.println("There are " + words.inventory() + " elements in the set");
System.out.println("Enter a value to remove from the set: ");
input = kb.nextLine();
while (!words.contains(input))
{
System.out.println(input + " is not in the set");
System.out.println("Enter a value to remove from the set: ");
input = kb.nextLine();
}
words.remove(input);
System.out.println("There are now " + words.inventory() + " elements in the set");
System.out.println("The first 10 words in the set are: ");
for (int x=0; x<10; x++)
System.out.println(words.getFirstItem());
System.out.println("There are now " + words.inventory() + " elements in the set");
System.out.println("5 random words from the set are: ");
for (int x=0; x<5; x++)
System.out.println(words.getRandomItem());
System.out.println("There are now " + words.inventory() + " elements in the set");
}
}
For reading from a file I use this class:
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile {
private static String path;
public ReadFile(String file_path){
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
for (int j = 0; j < numberOfLines; j++) {
textData[j] = textReader.readLine();
}
textReader.close();
return textData;
}
static int readLines() throws IOException {
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while((aLine = bf.readLine()) != null){
numberOfLines++;
}
bf.close();
return numberOfLines;
}
}
then in the class main you can add this code and you edit the path so you can read a file an get an array out of it
public static void main(String args[]) throws IOException {
ReadFile r = new ReadFile("here you put the path that the user provide");
String[] text = r.OpenFile();
ArrayList<String> array = new ArrayList<>();
array.addAll(Arrays.asList(text));
}
If you have any questions let me know!

Getting InputMismatchException when reading an int from a file with Scanner

I am working on a program which imports a library from a generated file.
The file generates properly and is found by Scanner. The first line has a single int as written by
pw.println(cdarchive.getNumber());
Elsewhere in the code. This part seems to work fine.
This is the error I'm getting:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at no.hib.dat102.IO.readFile(IO.java:26)
at no.hib.dat102.Menu.start(Menu.java:34)
at no.hib.dat102.CdArchiveClient.main(CdArchiveClient.java:10)
The line it refers to is
int libSize = in.nextInt();
This is my method:
public class IO {
static final String DELIMITER = "#";
public static CdArchiveADT readFile(String filename) {
Scanner in = null;
CdArchiveADT cda = null;
try
{
File f = new File(filename+".txt");
in = new Scanner(f);
System.out.println(f);
in.useDelimiter(DELIMITER);
int libSize = in.nextInt();
System.out.println("libSize" + libSize);
cda = new CdArchive(libSize);
for (int i=0; i<libSize;i++) {
int inId = in.nextInt();
String inTitle= in.next();
String inArtist = in.next();
String inLabel = in.next();
String inGenre = in.next();
int inYear = in.nextInt();
in.nextLine();
cda.addCd(new CD(inId, inArtist, inTitle, inYear, inGenre, inLabel));
System.out.println("Closing Scanner (input)");
in.close();
}
}
catch (FileNotFoundException e){
System.out.println("Config file not found!");
e.printStackTrace();
}
return cda;
}
EDIT:
This is the method that writes to the file:
public static void writeFile(CdArchiveADT cdarchive, String filename) throws IOException {
PrintWriter pw = null;
File file = null;
try {
file = new File(filename +".txt");
// Create the file if it does not already exist
file.createNewFile();
// Writing metadata
pw = new PrintWriter(new FileWriter(file, false));
pw.println(cdarchive.getNumber());
// Writing data, if CdArchive is not empty
if (cdarchive.getCdTable()[0] != null) {
for (int i = 0; i<cdarchive.getNumber(); i++ ) {
CD c = cdarchive.getCdTable()[i];
pw.print(c.getId()); pw.print(DELIMITER);
pw.print(c.getTitle()); pw.print(DELIMITER);
pw.print(c.getArtist()); pw.print(DELIMITER);
pw.print(c.getLabel()); pw.print(DELIMITER);
pw.print(c.getGenre()); pw.print(DELIMITER);
pw.print(c.getYear()); pw.println(DELIMITER);
}
}
}
catch (FileNotFoundException e)
{
System.out.println("File not found!");
e.printStackTrace();
}
finally
{
if ( pw != null )
{
System.out.println("Closing PrintWriter");
pw.close();
}
}
}
I got a working example:
public static void main(String[] args) {
// write
String delimiter = "#";
StringWriter stringWriter = new StringWriter();
PrintWriter pw = new PrintWriter(stringWriter);
pw.println(3);
for (int i = 0; i < 3; i++) {
pw.print("id " + i);
pw.print(delimiter);
pw.print("titel " + i);
pw.print(delimiter);
pw.print("artist " + i);
pw.println(delimiter);
}
String theString = stringWriter.toString();
System.out.println(theString);
try {
pw.close();
stringWriter.close();
} catch (IOException e) {
// ignore in example
}
// read
Scanner in = new Scanner(theString);
in.useDelimiter("\\s*#\\s*|\\s*\n\\s*"); // add new line as delimiter aswell
int libSize = in.nextInt();
for (int i = 0; i < libSize; i++) {
String inId = in.next();
String inTitle = in.next();
String inArtist = in.next();
in.nextLine();
System.out.println("read: " + inId + ", " + inTitle + ", " + inArtist);
}
in.close();
}
The point is to add new line to the used delimiters aswell
try to use
static final String DELIMITER = "\\s*#\\s*";
Otherwise any leading or trailing spaces will cause that error.

Make faster a read from file

I'm going to pass my data from MongoDB to Neo4j.
So, I exported my MongoDB documents in .csv. As you can read here I have a problem with the array uniform.
So I wrote a java program to fix this problem.
Here is the .csv exported from MongoDB (note the different about uniform array):
_id,official_name,common_name,country,started_by.day,started_by.month,started_by.year,championship,stadium.name,stadium.capacity,palmares.first_prize,palmares.second_prize,palmares.third_prize,palmares.fourth_prize,average_age,squad_value,foreigners,uniform
0,yaDIXxLAOV,WWYWLqPcYM,QsVwiNmeGl,7,9,1479,oYKGgstIMv,qskcxizCkd,8560,10,25,9,29,16,58,6,"[""first_colour"",""second_colour"",""third_colour""]"
Here is how it must be to import in Neo4j:
_id,official_name,common_name,country,started_by.day,started_by.month,started_by.year,championship,stadium.name,stadium.capacity,palmares.first_prize,palmares.second_prize,palmares.third_prize,palmares.fourth_prize,average_age,squad_value,foreigners,uniform.0,uniform.1,uniform.2
0,yaDIXxLAOV,WWYWLqPcYM,QsVwiNmeGl,7,9,1479,oYKGgstIMv,qskcxizCkd,8560,10,25,9,29,16,58,6,first_colour,second_colour,third_colour
My code works, but I have to convert 500k line of the .csv file and the program it is too much slow(it's still working after 20 minutes :/):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class ConvertireCSV {
public static void main(String[] args) throws IOException {
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
b=new BufferedReader(f);
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
String line="";
String csv="";
while(true) {
line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
csv=csv+line;
}
File file = new File("outputForNeo4j.csv");
if(file.createNewFile()) {
PrintWriter pw = new PrintWriter(file);
pw.println(firstLine + csv);
System.out.println("New file \"outputForNeo4j.csv\" created.");
pw.flush();
pw.close();
}
}
}
How can I make it faster?
Okay some basic ways to improve your code:
Make sure that your variables got the minimal scope required. If you don't need line outside your loop, don't declare it outside your loop.
Concatenation of simple strings is in general slow. Use a StringBuilder to speed things to there.
Why are you buffering the string anyway? Seems like a waste of memory. Just open the output stream to your target file and write the lines to the new file as you process them.
Examples:
I don't think you need a example on the first point.
For the second things could look like this:
...
StringBuilder csv = new StringBuilder();
while(true) {
...
csv.append(line);
}
...
if(file.createNewFile()) {
...
pw.println(firstLine + csv.toString());
...
}
For the third point the rewriting would be a little more extensive:
public static void main(String[] args) throws IOException {
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
b=new BufferedReader(f);
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
File file = new File("outputForNeo4j.csv");
if(!file.createNewFile()) {
// all work would be for nothing! Bailing out.
return;
}
PrintWriter pw = new PrintWriter(file);
pw.print(firstLine);
while(true) {
String line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
pw.print(line);
}
System.out.println("New file \"outputForNeo4j.csv\" created.");
pw.flush();
pw.close();
b.close()
}
csv=csv+line;
string concatenation is expensive operation. I would suggest using bufferedWriter.
something like this:
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
BufferedWriter out;
b=new BufferedReader(f);
try{
out = new BufferedWriter(new FileWriter("outputForNeo4j.csv"));
} catch(Exception e){
//cannot create file
}
System.out.println("New file \"outputForNeo4j.csv\" created.");
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
String line="";
String csv="";
out.write(firstLine);
while(true) {
line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
out.write(line);
}
out.flush();
}
Results :
test0 : Runs: 241 iterations ,avarage milis = 246
test1 : Runs: 249 iterations ,avarage milis = 118
test2 : Runs: 269 iterations ,avarage milis = 5
test3 : Runs: 241 iterations ,avarage milis = 2
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Random;
public class Tester {
private static final String filePath = "c:\\bigFile.txt";
//private static final String filePath = "c:\\bigfileNewLine.txt";
private static final int numOfMethods = 4;
private static final int numOfIter = 1000;
public Tester() throws NoSuchMethodException {
System.out.println("Tester.Tester");
int[] milisArr = new int [numOfMethods];
int[] actualRun = new int [numOfMethods];
Random rnd = new Random(System.currentTimeMillis());
Long startMs = 0l, endMs = 0l;
Method[] method = new Method[numOfMethods];
for (int i = 0; i < numOfMethods; i++)
method[i] = this.getClass().getMethod("test" + i);
int testCount = 0;
while (testCount++ < numOfIter) {
int testMethod = rnd.nextInt(numOfMethods);
Method m = method[testMethod];
try {
System.gc();
startMs = System.currentTimeMillis();
String retval = (String) m.invoke(null);
endMs = System.currentTimeMillis();
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvocationTargetException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
milisArr[testMethod] += (endMs - startMs);
actualRun[testMethod]++;
System.out.println("Test name: " + m.getName() + " testCount=" + testCount + " Of " + numOfIter + " iteration, Total time :" + (endMs - startMs) / 1000.0 + " seconds");
}
System.out.println("Test Summery :");
for (int i = 0; i < numOfMethods; i++)
System.out.println("test" + i + " : Runs: " + actualRun[i] + " iterations ,avarage milis = " + milisArr[i]/numOfIter);
}
public static String test0() throws IOException {
InputStream file = getInputStream();
StringBuffer textBuffer = new StringBuffer();
int c;
while ((c = file.read()) != -1)
textBuffer.append((char) c);
file.close();
return textBuffer.toString();
}
public static String test1() throws IOException {
Reader reader = new FileReader(new File(filePath));
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();
String result = line;
while (line != null) {
line = br.readLine();
if (line == null) {
} else {
result = result + "\n" + line;
}
}
br.close();
reader.close();
return result;
}
public static String test2() throws IOException {
byte[] buf = new byte[1024];
int l;
InputStream is = getInputStream();
StringBuffer tmpBuf = new StringBuffer();
while ((l = is.read(buf)) != -1) {
tmpBuf.append(new String(buf, 0, l));
}
is.close();
return tmpBuf.toString();
}
public static String test3() throws IOException {
File source = new File(filePath);
final DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(source)));
final byte[] buffer = new byte[(int) source.length()];
dis.readFully(buffer);
dis.close();
return new String(buffer, "UTF-8");
}
private static InputStream getInputStream() {
try {
return new FileInputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
try {
new Tester();
} catch (NoSuchMethodException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}

Search a file for a String and return that String if found

How can you search through a txt file for a String that the user inputs and then return that String to the console. I've written some code that doesn't work below, but I hope it can illustrate my point...
public static void main(String[] args) {
searchforName();
}
private static void searchForName() throws FileNotFoundException {
File file = new File("leaders.txt");
Scanner kb = new Scanner(System.in);
Scanner input = new Scanner(file);
System.out.println("Please enter the name you would like to search for: ");
String name = kb.nextLine();
while(input.hasNextLine()) {
System.out.println(input.next(name));
}
}
The "leaders.txt" file contains a list of names.
You can create a seperate Scanner to read the file line by line and do a match that way...
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(name)) {
// a match!
System.out.println("I found " +name+ " in file " +file.getName());
break;
}
}
With regards to whether you should use a Scanner or a BufferedReader to read the file, read this answer.
Scanner is way too slow. Run the following code, and see the differences. Searched in 750 MB file, and BufferedReader is 10 times faster than Scanner on average.
package uk.co.planetbeyond.service.test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.Scanner;
public class SearchTextInFile
{
public static void main(String[] args) throws IOException
{
// First write a file, with large number of entries
writeFile("/home/aqeel/temp/subscribers_files.csv");
long scannerSearchMillis = 0;
long brSearchMillis = 0;
int iterations = 5;
// Now search random strings five times, and see the time taken
for (int i = 0; i < iterations; i++)
{
String msisdn = String.valueOf(923000000000l + ((long) (Math.random() * 40000000)));
System.out.println("ITERATION " + i);
System.out.print("Search " + msisdn + " using scanner");
Date d1 = new Date();
searchUsingScanner("/home/aqeel/temp/subscribers_files.csv", msisdn);
Date d2 = new Date();
long millis = (d2.getTime() - d1.getTime());
scannerSearchMillis += millis;
System.out.println(" | " + (millis / 1000) + " Seconds");
System.out.println("==================================================================");
System.out.print("Search " + msisdn + " using buffered reader");
d1 = new Date();
searchUsingBufferedReader("/home/aqeel/temp/subscribers_files.csv", msisdn);
d2 = new Date();
millis = d2.getTime() - d1.getTime();
brSearchMillis += millis;
System.out.println(" | " + (millis / 1000) + " Seconds");
System.out.println("==================================================================");
System.out.println("==================================================================");
System.out.println("==================================================================");
System.out.println("==================================================================");
}
System.out.println("Average Search time using Scanner " + (scannerSearchMillis / (iterations * 1000.0)) + " Seconds");
System.out.println("Average Search time using BufferedReader " + (brSearchMillis / (iterations * 1000.0)) + " Seconds");
}
public static void writeFile(String path)
{
BufferedWriter csvWriter = null;
HashSet<Integer> additions = new HashSet<Integer>();
try
{
csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));
for (int i = 0; i < 40000000; i++)
{
int addition = (int) (Math.random() * 40000000);
additions.add(addition);
if (i % 20000 == 0)
{
System.out.println("Entries written : " + i + " ------ Unique Entries: " + additions.size());
csvWriter.flush();
}
long msisdn = 923000000000l + addition;
csvWriter.write(String.valueOf(msisdn) + "|" + String.valueOf((int) (Math.random() * 131)) + "\r\n");
}
csvWriter.flush();
System.out.println("Unique Entries written : " + additions.size());
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if (csvWriter != null)
{
try
{
csvWriter.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static String searchUsingScanner(String filePath, String searchQuery) throws FileNotFoundException
{
searchQuery = searchQuery.trim();
Scanner scanner = null;
try
{
scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
if (line.contains(searchQuery))
{
return line;
}
else
{
}
}
}
finally
{
try
{
if (scanner != null)
scanner.close();
}
catch (Exception e)
{
System.err.println("Exception while closing scanner " + e.toString());
}
}
return null;
}
public static String searchUsingBufferedReader(String filePath, String searchQuery) throws IOException
{
searchQuery = searchQuery.trim();
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
String line;
while ((line = br.readLine()) != null)
{
if (line.contains(searchQuery))
{
return line;
}
else
{
}
}
}
finally
{
try
{
if (br != null)
br.close();
}
catch (Exception e)
{
System.err.println("Exception while closing bufferedreader " + e.toString());
}
}
return null;
}
}
The following Java 7+ solution has a main advantage.
private static void searchForName() throws IOException {
System.out.println("Please enter the name you would like to search for: ");
Scanner kb = new Scanner(System.in);
String name = kb.nextLine();
List<String> lines = Files.readAllLines(Paths.get("leaders.txt"));
for (String line : lines) {
if (line.contains(name)) {
System.out.println(line);
}
}
}
It's not shorter than the the code from this answer. The main point is, when we open a File we have an open resource and we have to care about closing it. Otherwise it might pose a resource leak.
As of Java 7 the try-with-resources statement handles closing of resources. So opening a Scanner backed by a file would look like that:
try (Scanner scanner = new Scanner("leaders.txt")) {
// using scanner
}
Using Files.readAllLines we don't need to care about closing the file since this method (JavaDoc)
ensures that the file is closed when all bytes have been read or an
I/O error, or other runtime exception, is thrown.
If the first occourance of a String is needed only, the following Java 8+ code does the job in few lines:
protected static Optional<String> searchForName(String name) throws IOException {
try (Stream<String> lines = Files.lines(Paths.get("leaders.txt"))) {
return lines.filter(line -> line.contains(name)).findFirst();
}
}
It returns an Optional indicating that there might be an empty result. We use it i.e. as follows:
private static void searchForName() throws IOException {
System.out.println("Please enter the name you would like to search for: ");
Scanner kb = new Scanner(System.in);
String name = kb.nextLine();
Optional<String> result = searchForName(name);
result.ifPresent(System.out::println);
}

Categories