Search in a text file (with specific pattern) - java

The text file looks something like this:
keyword12x:
=========
Acon:
a1
x2
z3
Bcon:
c1
e2
w3
r4
and so on... (always the same sheme and a lot of keywords in the file)
I need a function that I can pass keyword12x and the signal type that I'm looking for which searches through the text file and returns the corresponding Acon or Bcon singnals
Exaple declaration:
public string searchKey(string keyword, string type){
....
}
a call like:
search("keyword12x", "Acon")
outputs:
a1
x2
z3
(type = Bcon would obviously give c1, e2, w3, r4)
EDIT: This is what "I have".. (It's not what I want and only for testing porpose)
As you can see it's searching the "keyword12x" line and I'm stuck there.
import java.io.File;
import java.util.Scanner;
public class ReadText
{
public static void main(String[] args) throws Exception
{
File file =
new File("C:\\test.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()){
String line = sc.nextLine();
if(line.contains("keyword12x")){
System.out.println(line);
}
}
}
}
EDIT2:
> step by step "in english":
> 1. go trough lines
> 2. untill you find "keyword12x"
> 3. keep going through lines (from that point !)
> 4. find "Acon:"
> 5. go next line
> 6. start printing out and go next line (loop)
> 7. until line = "Bcon:" appears
> 8. go next line
> 9. start printing out and go next line (loop)
> 10. untill an empty line appears
EDIT3:
Lets resume: I want to search for a line containing the keyword (with a ':' appended), then (after that line) search for a line containing the given type (also followed by ':') and then gather all following lines up to, but not including a line that ends with ':' or empty line. [summary by #Carlos Heuberger]

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
static String readLine = "";
String ch ;
static File f = new File("/home/admin1/demoEx");
public String searchKey(String keyword, String type) throws IOException
{
ch = type.toLowerCase().substring(0, 1);
BufferedReader b = null;
try {
b = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Reading file using Buffered Reader");
while ((readLine = b.readLine()) != null)
{
if(readLine.contains(ch))
{
System.out.println(readLine);
}
}
return readLine;
}
public static void main(String args[])
{
try {
String x = (new Demo()).searchKey("keyword12x","Bcon");
} catch (IOException e) {
e.printStackTrace();
}
}
}
try this one.

Related

how to split one text into multiple text files

I have the following Text:
1
(some text)
/
2
(some text)
/
.
.
/
8519
(some text)
and I want to split this text into several text-files where each file has the name of the number before the text i.e. (1.txt, 2.txt) and so on, and the content of this file will be the text.
I tried this code
BufferedReader br = new BufferedReader(new FileReader("(Path)\\doc.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
// sb.append(System.lineSeparator());
line = br.readLine();
}
String str = sb.toString();
String[] arrOfStr = str.split("/");
for (int i = 0; i < arrOfStr.length; i++) {
PrintWriter writer = new PrintWriter("(Path)" + arrOfStr[i].charAt(0) + ".txt", "UTF-8");
writer.println(arrOfStr[i].substring(1));
writer.close();
}
System.out.println("Done");
} finally {
br.close();
}
this code works for files 1-9. However, things go wrong for files 10-8519 since I took the first number in the string (arrOfStr [i].charAt(0)) I know my solution is insufficient any suggestions?
In addition to my comment, considering there isn't a space between the leading integer and the first word, the substring at the first space doesn't work.
This question/answer has a few options that should help, the one using regex (\d+) being the simplest one imo, and copied below.
Matcher matcher = Pattern.compile("\\d+").matcher(arrOfStr[i]);
matcher.find();
int yourNumber = Integer.valueOf(matcher.group());
Given a string find the first embedded occurrence of an integer
As you mentioned, the problem is that you only take the first digit. You could enumerate the first characters until you find a non digit character ( arrOfStr[i].charAt(j) <'0' || arrOfStr[i].charAt(j) > '9' ) but it shoud be easier to user a Scanner and an appropriate regexp.
int index = new Scanner(arrOfStr[i]).useDelimiter("\\D+").nextInt();
The delimiter is precisely any group of non-digit character
Here is a quick solution for the given problem. You can test and do proper exception handling.
package practice;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class FileNioTest {
public static void main(String[] args) {
Path path = Paths.get("C:/Temp/readme.txt");
try {
List<String> contents = Files.readAllLines(path);
StringBuffer sb = new StringBuffer();
String folderName = "C:/Temp/";
String fileName = null;
String previousFileName = null;
// Read from the stream
for (String content : contents) {// for each line of content in contents
if (content.matches("-?\\d+")) { // check if it is a number (based on your requirement)
fileName = folderName + content + ".txt"; // create a file name with path
if (sb != null && sb.length() > 0) { // this means if content present to write in the file
writeToFile(previousFileName, sb); // write to file
sb.setLength(0); // clearing buffer
}
createFile(fileName); // create a new file if number found in the line
previousFileName = fileName; // store the name to write content in previous opened file.
} else {
sb.append(content); // keep storing the content to write in the file.
}
System.out.println(content);// print the line
}
if (sb != null && sb.length() > 0) {
writeToFile(fileName, sb);
sb.setLength(0);
}
} catch (IOException ex) {
ex.printStackTrace();// handle exception here
}
}
private static void createFile (String fileName) {
Path newFilePath = Paths.get(fileName);
if (!Files.exists(newFilePath)) {
try {
Files.createFile(newFilePath);
} catch (IOException e) {
System.err.println(e);
}
}
}
private static void writeToFile (String fileName, StringBuffer sb) {
try {
Files.write(Paths.get(fileName), sb.toString().getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
System.err.println(e);
}
}
}

Read a line and push into a line-stack until the end of file

I have to do a program and unfortunately I have no idea where to start. It's like we were doing very basic coding and then my teacher went on maternity leave and our substitute thinks we are further along then we actually are. I know how to ready from a file, but I do not know how to put the line into a stack from there.
These are the instructions
1) Read a line and push into a line-stack until the end of file 2) While line_stack is not empty a. Pop one element out and process the following i. Split elements in this line (i.e. numbers) using StringTokenzier ii. Push all numbers into number-stack iii. While number_stack is not empty 1. Pop a number 2. Print a character using that ascii number
If I understand the problem correctly you need to:
Represent a line as a java.lang.String.
Then using java.util.Stack create a Stack< String> and put all the lines there.
Use java.util.StringTokenizer to split each line into multiple parts. Each part will be a String itself.
Turn each part of the line into a number using Integer.valueOf(String)
Put all the numbers into a Stack< Integer>.
Print the right character for each number by casting integer value to char.
I think this may be the solution for your problem:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;
public class LinesProcessor {
private static Stack<String> readLinesFromFile(String fileName) throws IOException {
Stack<String> lines = new Stack<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
String line = null;
while ((line = br.readLine()) != null) {
lines.push(line);
}
}
return lines;
}
private static void processNumbers(Stack<Integer> stackOfNumbers) {
while (!stackOfNumbers.empty()) {
Integer number = stackOfNumbers.pop();
System.out.print((char) number.intValue());
}
}
private static void processLine(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
Stack<Integer> stackOfNumbers = new Stack<>();
while (tokenizer.hasMoreTokens()) {
Integer number = Integer.valueOf(tokenizer.nextToken());
stackOfNumbers.push(number);
}
processNumbers(stackOfNumbers);
}
private static void processLines(Stack<String> stackOfLines) {
while (!stackOfLines.empty()) {
String currentLine = stackOfLines.pop();
processLine(currentLine);
}
}
public static void main(String[] args) throws IOException {
if (args.length < 1) {
System.out.println("Name of file missing");
System.exit(1);
}
String fileName = args[0];
Stack<String> stackOfLines = readLinesFromFile(fileName);
processLines(stackOfLines);
}
}

Want to know reason behind NumberFormat Exception in my code

I am trying to read file with BufferedReader and at the time of spliting each line of file I want to convert string data at 8th position to be converted to float.(count starts from 0 data)
below is my code :
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TestFloat {
static BufferedReader bin;
String line;
void sumAmount() throws IOException //Perform calculation
{
bin = new BufferedReader(new FileReader("D:\\Extras\\file.txt"));
//String firstline = bin.readLine();
while ((line = bin.readLine()) != null)
{
String data[] = line.split(",");
//System.out.println(data[8]);
System.out.println(Float.valueOf(data[8]));
//System.out.println(java.lang.Float.parseFloat(data[8]))
}
}
public static void main(String[] args)
{
TestFloat ts = new TestFloat();
try {
ts.sumAmount();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for this code I am getting exception as below :
Exception in thread "main" java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:451)
at java.lang.Float.valueOf(Float.java:416)
at TestFloat.sumAmount(TestFloat.java:17)
at TestFloat.main(TestFloat.java:24)
one sample line of file.txt is :
20,20160518,262,20160518,00,F&O ABC DEBIT F 160518,000405107289,000405006220,5000000.00,5000000.00,0.00,,
I have tried with parseFloat and valueOf both function but it shows exception. What is the reason behind the fail?
java.lang.NumberFormatException: empty String
as the error states you're attempting to parse an empty string.
one solution is to use an if statement to guard off the NumberFormatException(only for empty strings that is, you could still get the NumberFormatException for unparseable strings).
if(data[8] != null && data[8].length() > 0){
System.out.println(Float.valueOf(data[8]));
System.out.println(java.lang.Float.parseFloat(data[8]));
}
you'll need to go through the debugger step by step and see what is the real issue behind it.

(Java) how to read a text file block by block

suppose I have the following text file, how do I read each block of lines separated by 2 empty lines in Java?
Thanks!
Reference Type: Journal Article
Record Number: 153
Author: Yang, W. and Kang, J.
Year: 2005
Title: Acoustic comfort evaluation in urban open public spaces
Journal: Applied Acoustics
Volume: 66
Issue: 2
Pages: 211-229
Short Title: Acoustic comfort evaluation in urban open public spaces
ISSN: 0003682X
DOI: 10.1016/j.apacoust.2004.07.011
'File' Attachments: internal-pdf://0633242026/Acoustic comfort evaluation in urban open public spaces.pdf
Reference Type: Thesis
Record Number: 3318
Author: Wienold, Jan
Year: 2009
Title: Daylight glare in offices
University: Fraunhofer Institute for Solar Energy Systems ISE
Thesis Type: PhD Dissertation
Short Title: Daylight glare in offices
URL: http://publica.fraunhofer.de/eprints/urn:nbn:de:0011-n-1414579.pdf
'File' Attachments: internal-pdf://2172014641/Daylight glare in offices.pdf
It seems that answering questions in this forum is quite picky ... I think its really not necessary. Nevertheless, here's my try via Processing, a programming environment built on top of Java:
import java.util.*;
String fileName = "";
String line;
BufferedReader br;
void setup(){
fileName = "My_EndNote_Library_2014-07-04.txt";
br = createReader(fileName);
}
void draw(){
try {
line = br.readLine();
println(line);
println();
} catch (IOException e) {
e.printStackTrace();
line = null;
}
if (line == null) {
// Stop reading because of an error or file is empty
noLoop();
}
}
Since data (rows) of each block is not the same you can do something like this. Using \n\n as delimiter for each block and \n for each line
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
StringBuffer sb = new StringBuffer();
while (true) {
String line = br.readLine();
if (line == null) break;
sb.append(line).append("\n");
}
String[] blocks = sb.toString().split("\n\n");
for (String block : blocks) {
block = block.trim();
// block - individual block from file
String[] data = block.split("\n");
for (String d : data) {
// d - individual line of block
}
}
}
}
There are two flaws in accepted answer though essence of logic is correct that you don't need any complex regex etc ,
1.Code is not OS neutral since \n is hard coded
2.Second, since a \n is added after each line so there would be three \n chars between two blocks instead of two \n chars ( two from two empty lines and one extra from previous block ) . Splitting on two chars will also work but block-1 on wards would contain an extra new line at the beginning so you might require trim .
Code is assuming that file is on class path & not on disk.
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ReferenceType {
public static void main(String[] args) {
ReferenceType app = new ReferenceType();
String allLines = null;
String[] blocks = null;
String lineSeparator = System.getProperty("line.separator");
try {
allLines = app.getFileAsString(lineSeparator);
blocks = allLines.split(lineSeparator+lineSeparator+lineSeparator);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getFileAsString(String lineSeparator) throws URISyntaxException, IOException {
Path path = Paths.get(this.getClass().getResource("ReferenceType.txt").toURI());
String textLine = null;
StringBuilder builder = new StringBuilder();
try (BufferedReader br = Files.newBufferedReader(path)) {
while ((textLine = br.readLine()) != null) {
builder.append(textLine);
builder.append(lineSeparator);
}
}
return builder.toString();
}
}

How can I parse through a file for a string matching a generated string?

My bad for the title, I am usually not good at making those.
I have a programme that will generate all permutations of an inputted word and that is supposed to check to see if those are words (checks dictionary), and output the ones that are. Really I just need the last the part and I can not figure out how to parse through a file.
I took out what was there (now displaying the "String words =") because it really made thing worse (was an if statement). Right now, all it will do is output all permutations.
Edit: I should add that the try/catch was added in when I tried turning the file in a list (as opposed to the string format which it is currently in). So right now it does nothing.
One more thing: is it possible (well how, really) to get the permutations to display permutations with lesser characters than entered ? Sorry for the bad wording, like if I enter five characters, show all five character permutations, and four, and three, and two, and one.
import java.util.List;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import static java.lang.System.out;
public class Permutations
{
public static void main(String[] args) throws Exception
{
out.println("Enter anything to get permutations: ");
Scanner scan = new Scanner(System.in);
String io = scan.nextLine();
String str = io;
StringBuffer strBuf = new StringBuffer(str);
mutate(strBuf,str.length());
}
private static void mutate(StringBuffer str, int index)
{
try
{
String words = FileUtils.readFileToString(new File("wordsEn.txt"));
if(index <= 0)
{
out.println(str);
}
else
{
mutate(str, index - 1);
int currLoc = str.length()-index;
for (int i = currLoc + 1; i < str.length(); i++)
{
change(str, currLoc, i);
mutate(str, index - 1);
change(str, i, currLoc);
}
}
}
catch(IOException e)
{
out.println("Your search found no results");
}
}
private static void change(StringBuffer str, int loc1, int loc2)
{
char t1 = str.charAt(loc1);
str.setCharAt(loc1, str.charAt(loc2));
str.setCharAt(loc2, t1);
}
}
If each word in your file is actually on a different line, maybe you can try this:
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null)
{
... // check and print here
}
Or if you want to try something else, the Apache Commons IO library has something called LineIterator.
An Iterator over the lines in a Reader.
LineIterator holds a reference to an open Reader. When you have finished with the iterator you should close the reader to free internal resources. This can be done by closing the reader directly, or by calling the close() or closeQuietly(LineIterator) method on the iterator.
The recommended usage pattern is:
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
it.close();
}

Categories