Как найти строку в файле java

let’s say I have a txt file containing:

john
dani
zack

the user will input a string, for example “omar”
I want the program to search that txt file for the String “omar”, if it doesn’t exist, simply display “doesn’t exist”.

I tried the function String.endsWith() or String.startsWith(), but that of course displays “doesn’t exist” 3 times.

I started java only 3 weeks ago, so I am a total newbie…please bear with me.
thank you.

asked Dec 6, 2013 at 7:21

user3040333's user avatar

Just read this text file and put each word in to a List and you can check whether that List contains your word.

You can use Scanner scanner=new Scanner("FileNameWithPath"); to read file and you can try following to add words to List.

 List<String> list=new ArrayList<>();
 while(scanner.hasNextLine()){
     list.add(scanner.nextLine()); 

 }

Then check your word is there or not

if(list.contains("yourWord")){

  // found.
}else{
 // not found
}

BTW you can search directly in file too.

while(scanner.hasNextLine()){
     if("yourWord".equals(scanner.nextLine().trim())){
        // found
        break;
      }else{
       // not found

      }

 }

answered Dec 6, 2013 at 7:22

Ruchira Gayan Ranaweera's user avatar

7

use String.contains(your search String) instead of String.endsWith() or String.startsWith()

eg

 str.contains("omar"); 

answered Dec 6, 2013 at 7:22

Prabhakaran Ramaswamy's user avatar

You can go other way around. Instead of printing ‘does not exist’, print ‘exists’ if match is found while traversing the file and break; If entire file is traversed and no match was found, only then go ahead and display ‘does not exist’.

Also, use String.contains() in place of str.startsWith() or str.endsWith(). Contains check will search for a match in the entire string and not just at the start or end.

Hope it makes sense.

answered Dec 6, 2013 at 7:24

Ankur Shanbhag's user avatar

Ankur ShanbhagAnkur Shanbhag

7,7062 gold badges28 silver badges38 bronze badges

0

Read the content of the text file: http://www.javapractices.com/topic/TopicAction.do?Id=42

And after that just use the textData.contains(user_input); method, where textData is the data read from the file, and the user_input is the string that is searched by the user

UPDATE

public static StringBuilder readFile(String path) 
 {       
        // Assumes that a file article.rss is available on the SD card
        File file = new File(path);
        StringBuilder builder = new StringBuilder();
        if (!file.exists()) {
            throw new RuntimeException("File not found");
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

       return builder;
    }

This method returns the StringBuilder created from the data you have read from the text file given as parameter.

You can see if the user input string is in the file like this:

int index = readFile(filePath).indexOf(user_input);
        if ( index > -1 )
            System.out.println("exists");

answered Dec 6, 2013 at 7:25

Hitman's user avatar

HitmanHitman

5884 silver badges10 bronze badges

1

You can do this with Files.lines:

try(Stream<String> lines = Files.lines(Paths.get("...")) ) {
    if(lines.anyMatch("omar"::equals)) {
  //or lines.anyMatch(l -> l.contains("omar"))
        System.out.println("found");
    } else {
        System.out.println("not found");
    }
}

Note that it uses the UTF-8 charset to read the file, if that’s not what you want you can pass your charset as the second argument to Files.lines.

answered Sep 19, 2018 at 6:40

Alex - GlassEditor.com's user avatar

Fast comes at a price…. code complexity and perhaps readability.

Assuming that your code produces the right results now…. and it is a big assumption because:

  • it expects the word to be at the beginning/end of the line, or surrounded by spaces (not commas, punctuation, etc.)
  • it does not look for the word inside another string, it will match ‘are’, but not ‘bare’.

OK, a much faster way (keeping it as Java), is to do the following:

  1. Convert the search string (‘are’) to a byte-array in the same encoding as the file.
  2. Open a memory-mapped byte-buffer from a File-Channel on the file.
  3. Scan the ByteBuffer, looking for matches to the search byte-array
  4. count the newlines as you go.
  5. close the ByteBuffer

If the file is larger than your memory, you will have to re-position the byte-buffer occasionally. I recommend using a emopry-mapped size of about 4MB plus the size of the search-string. That way you can search the 4MB window, and then start the next window at the next 4mb boundary.

Once you get in to it, it will make sense.

This system will be fast because you will never have to copy the file’s data in to Java. Everything will actually happen in the native side of things.

There is a lot to read to make it work.

I would start with a tutorial….

  • StudyTrails
  • Yaldix
  • LinuxTopia

of course, if you want really fast, use grep.

Here is some example code that may get you started:

import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;


public class NIOGrep {

    public static void main(String[] args) throws IOException {
        if (args.length != 2) {
            throw new IllegalArgumentException();
        }
        String grepfor = args[0];
        Path path = Paths.get(args[1]);

        String report = searchFor(grepfor, path);

        System.out.println(report);

    }

    private static final int MAPSIZE = 4 * 1024 ; // 4K - make this * 1024 to 4MB in a real system.

    private static String searchFor(String grepfor, Path path) throws IOException {
        final byte[] tosearch = grepfor.getBytes(StandardCharsets.UTF_8);
        StringBuilder report = new StringBuilder();
        int padding = 1; // need to scan 1 character ahead in case it is a word boundary.
        int linecount = 0;
        int matches = 0;
        boolean inword = false;
        boolean scantolineend = false;
        try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
            final long length = channel.size();
            int pos = 0;
            while (pos < length) {
                long remaining = length - pos;
                // int conversion is safe because of a safe MAPSIZE.. Assume a reaosnably sized tosearch.
                int trymap = MAPSIZE + tosearch.length + padding;
                int tomap = (int)Math.min(trymap, remaining);
                // different limits depending on whether we are the last mapped segment.
                int limit = trymap == tomap ? MAPSIZE : (tomap - tosearch.length);
                MappedByteBuffer buffer = channel.map(MapMode.READ_ONLY, pos, tomap);
                System.out.println("Mapped from " + pos + " for " + tomap);
                pos += (trymap == tomap) ? MAPSIZE : tomap;
                for (int i = 0; i < limit; i++) {
                    final byte b = buffer.get(i);
                    if (scantolineend) {
                        if (b == 'n') {
                            scantolineend = false;
                            inword = false;
                            linecount ++;
                        }
                    } else if (b == 'n') {
                        linecount++;
                        inword = false;
                    } else if (b == 'r' || b == ' ') {
                        inword = false;
                    } else if (!inword) {
                        if (wordMatch(buffer, i, tomap, tosearch)) {
                            matches++;
                            i += tosearch.length - 1;
                            if (report.length() > 0) {
                                report.append(", ");
                            }
                            report.append(linecount);
                            scantolineend = true;
                        } else {
                            inword = true;
                        }
                    }
                }
            }
        }
        return "Times found at--" + matches + "nWord found at--" + report;
    }

    private static boolean wordMatch(MappedByteBuffer buffer, int pos, int tomap, byte[] tosearch) {
        //assume at valid word start.
        for (int i = 0; i < tosearch.length; i++) {
            if (tosearch[i] != buffer.get(pos + i)) {
                return false;
            }
        }
        byte nxt = (pos + tosearch.length) == tomap ? (byte)' ' : buffer.get(pos + tosearch.length); 
        return nxt == ' ' || nxt == 'n' || nxt == 'r';
    }
}

Untried, but probably the fastest mechanism is to first, take your search key and encode it like the file.

For example, if you know the file is UTF-8, take your key and encode it from a String (which it UTF-16) in to a byte array that is UTF-8. This is important because by encoding down to the file representation, you’re only encoding the key. Using standard Java Readers goes the other way — converts the file to UTF-16.

Now that you have a proper key, in bytes, use NIO to create a MappedByteBuffer for the file. This maps the file in to the virtual memory space.

Finally, implement a Boyer-Moore algorithm for string search, using the bytes of the key against the bytes of the file via the mapped region,

There may well be a faster way, but this solves a bulk of the problems with searching a text file in Java. It leverages the VM to avoid copying large chunks of the file, and it skips the conversion step of whatever encoding the file is in to UTF-16, which Java uses internally.


This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

Show hidden characters

package com.javarush.task.task18.task1822;
/*
Поиск данных внутри файла
Считать с консоли имя файла.
Найти в файле информацию, которая относится к заданному id, и вывести ее на экран в виде, в котором она записана в файле.
Программа запускается с одним параметром: id (int).
Закрыть потоки.
В файле данные разделены пробелом и хранятся в следующей последовательности:
id productName price quantity
где id – int.
productName – название товара, может содержать пробелы, String.
price – цена, double.
quantity – количество, int.
Информация по каждому товару хранится в отдельной строке.
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String file = bufferedReader.readLine();
bufferedReader.close();
ArrayList<String> list = new ArrayList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
list.add(line);
}
for (String id : list) {
if (id.startsWith(args[0] + ” “)) {
System.out.println(id);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*Требования:
1. Программа должна считать имя файла с консоли.
2. Создай для файла поток для чтения.
3. Программа должна найти в файле и вывести информацию о id, который передается первым параметром.
4. Поток для чтения из файла должен быть закрыт.*/

Kolya1114

1 / 1 / 1

Регистрация: 01.12.2012

Сообщений: 116

1

Поиск слова в файле

16.09.2014, 12:36. Показов 25460. Ответов 2

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Написать программу для поиска слова в файле, программа должна показать: количество таких слов в файле, для каждого найденного слова: номер строки, и номер слова в строке. Искомое слово вводим с клавиатуры.
Я так думал что нужно сначала весь текст файла записать в ArrayList, но у меня не получается сделать поиск по файлу и вывести номер строки и номер слова в строке.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) throws IOException{
        FileReader fr = new FileReader("slovar");
        Scanner scan= new Scanner(fr);
        Scanner sc = new Scanner(System.in);
        String word = sc.nextLine();
        read("slovar");
        fillArray("slovar",word);
    }
    public static String read(String s) throws IOException{
        FileReader fr = new FileReader("slovar");
        Scanner scan= new Scanner(fr);  
        while(scan.hasNext()){
        System.out.println(scan.nextLine());
        }
        return s;
    }
    public static ArrayList<String> fillArray(String s,String word) throws IOException{
        ArrayList<String> list = new ArrayList();
        FileReader fr = new FileReader("slovar");
        Scanner scan= new Scanner(fr);
        while(scan.hasNext()){          
                list.add(scan.next());                      
        }
        System.out.println(list);       
        return list;
    }



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

16.09.2014, 12:36

2

2 / 2 / 0

Регистрация: 16.09.2014

Сообщений: 8

16.09.2014, 19:26

2

Зачем вам сохранять файл в ArrayList? Ищите сразу во время чтения файла.

Чуть позже напишу пример кода



0



_ViPeR_

614 / 488 / 175

Регистрация: 02.03.2010

Сообщений: 1,236

16.09.2014, 20:13

3

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) throws FileNotFoundException, IOException {
        String searchWord = "ходил"; // слово заменить на нужное
        FileInputStream fis = new FileInputStream(new File("E:/1.txt")); // путь заменить на нужный
        byte[] content = new byte[fis.available()];
        fis.read(content);
        fis.close();
        String[] lines = new String(content, "Cp1251").split("n"); // кодировку указать нужную
        int i = 1;
        for (String line : lines) {
            String[] words = line.split(" ");
            int j = 1;
            for (String word : words) {
                if (word.equalsIgnoreCase(searchWord)) {
                    System.out.println("Найдено в " + i + "-й строке, " + j + "-е слово");
                }
                j++;
            }
            i++;
        }
    }



3



Добавить комментарий