Find the file for String and return that String if found

As you can search in a txt file for the String string that the user enters, and then return that string to the console. I wrote code that does not 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 leader.txt file contains a list of names.

+5
source share
3 answers

You can create a separate Scanner to read the file line by line and make a match this 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; } } 

Regarding whether to use Scanner or BufferedReader to read the file, read this answer .

+11
source

Scanner is too slow. Run the following code and see the differences. Search in a file is 750 MB, and BufferedReader is on average 10 times faster than a scanner.

 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; } } 
+2
source

The following Java 7+ solution has a major 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); } } } 

This is no shorter than the code from this answer . The main thing is that when we open File we have an open resource, and we must take care to close it. Otherwise, this could result in a resource leak.

Starting with Java 7, the try-with-resources statement handles resource closures. Thus, opening a Scanner with a file will look like this:

 try (Scanner scanner = new Scanner("leaders.txt")) { // using scanner } 

Using Files.readAllLines we do not need to worry about closing the file, since this method ( JavaDoc )

ensures that the file is closed after reading all bytes or when an I / O error or other exception occurs at runtime.

If only the first occurrence of String is required, the following Java 8+ code does the work on multiple 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(); } } 

Returns Optional indicating that there may be an empty result. We use it, that is, 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); } 
+1
source

All Articles