Use Scanner on csv, iterate every time method is called - java

I am trying to parse a text document that has release notes and grab specific ones. To do that I have a csv with the desired release note keys. I want to scan the csv and use each key to find the matching section of the release note, and print the description that follows.
I would like to use the Scanner class for this to practice with it.
The csv looks like:
foobar-123,foobar-127,foobar-129
The release note text doc looks like:
foobar-123: ewkjhlq kghlhrekgh
foobar-124: lkjhfgrelgkj nberg
foobar-127: ljdfgl kjwneglkjn fdg
foobar-129: lguwlrkguj gwrlekgj werlktj
The issue I am running into is iterating through the csv. I seem to keep grabbing the first string in the csv. I am trying to figure out how to save my place in the csv, so every time the method is called, it goes to the next string.
I'm thinking I could create a variable that saves the last found string, and then use scanner to find that and then grab the next string. But that would require scanning through the csv each time I want to progress and which does not seem efficient. What would be the best way to iterate through the csv using the Scanner class?
Here is the code I have so far:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class ReleaseNotesScan {
public static void main(String[] args) {
//Open csv file with issue keys
Scanner getIssueKeys = null;
try {
getIssueKeys = new Scanner(new FileReader("resources/Issues.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Open release notes
Scanner releaseNotes = null;
try {
releaseNotes = new Scanner(new FileReader("resources/Release notes text.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Get issue key from csv
String issueKey = Finders.issueKey(getIssueKeys);
//The below three lines are just for testing if I am iterating through the csv
System.out.println(issueKey);
Finders.issueKey(getIssueKeys);
System.out.println(issueKey);
//Get issue key and description
String description = Finders.sectionContent(releaseNotes, issueKey);
System.out.println(issueKey + ": " + description);
//Close csv
getIssueKeys.close();
//Close release notes
releaseNotes.close();
}
}
My Finders class:
import java.util.Scanner;
public class Finders {
//parse csv
public static String issueKey(Scanner findIssues) {
findIssues.useDelimiter(",");
String issue = findIssues.next();
return issue;
}
public static String sectionContent(Scanner releaseNotes, String heading) {
while (releaseNotes.hasNextLine()){
String found = releaseNotes.findInLine(heading);
if (found != null){
releaseNotes.findInLine(": ");
String grabIt = releaseNotes.nextLine();
return grabIt;
}
releaseNotes.nextLine();
}
releaseNotes.close();
return "Not found";
}
}

Here is some example code to demonstrate how the application can be structured. I made some assumptions that the input file "issues" as a string (instead of a file, for brevity). The issues are stored in an array and release notes in HashMap collection. The release notes are read from the file, tokenized (split with ":" as delimiter) as the issue and its release-note text. The issue is the key and the release-note is the value in the map.
Finally, iterate each issue and get the corresponding release-note from the map.
Example Code:
import java.util.*;
import java.io.*;
public class MatchIssues {
private static String [] issues;
private static Map<String,String> releseNotes = new HashMap<>();
public static void main(String [] args)
throws IOException {
getIssues();
getReleaseNotes();
for(String issue : issues) {
// Match release notes for the issue
System.out.println(releseNotes.get(issue));
}
}
private static void getIssues() {
String s = "foobar-123,foobar-127,foobar-129"; // use string for demo
issues = s.split(",");
System.out.println(Arrays.toString(issues));
}
private static void getReleaseNotes()
throws IOException {
BufferedReader reader =
new BufferedReader(new FileReader("release_notes.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
String [] tokens = line.split(":");
releseNotes.put(tokens[0].trim(), tokens[1].trim());
}
System.out.println(releseNotes);
}
}
release_notes.txt:
foobar-123: aa ewk jhlq kghlhrekgh aa
foobar-124: bb lkjh fgrelgkj nberg bb
foobar-127: yy ljdfgl kjw neglkjn fdg yy
foobar-129: zz lgu wlrkguj gw rlekgj werlktj zz

Related

How to read text from a file between two given patterns in java8

I have one text file. I have to read contents between two given patterns.
for example lets I have a file names - datafromOU.txt
I have to need data from the pattern1 till pattern2.
pattern1 : "CREATE EXTR"
Pattern2 :";"
But problem is - file has multiple occurances of pattern2. So my requirement is to look for pattern1 and then search immediate occurance of pattern2 after the pattern1. I need to store this into one string and then process later.
Can you help me how to read data from pattern1 and immediate occurance of pattern2 into a string variable using java streams?
I use java8. Thanks a lot in advance.
Thanks.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Main {
static String getPatternFromString(String startPattern,String endPattern,String data) {
int startIndex=data.indexOf(startPattern);
data=data.substring(startIndex);
int endIndex=data.indexOf(endPattern, startIndex + startPattern.length());
data=data.substring(0,endIndex+1);
return data;
}
public static void main(String[] args) throws IOException {
File file1 = new File("C:\\Users\\amish\\Desktop\\partie.txt");
String startPattern="CREATE EXTR";
String endPattern=";";
try (BufferedReader leBuffer1 = new BufferedReader(new FileReader(file1));) {
StringBuilder everything = new StringBuilder();
String line;
while ((line = leBuffer1.readLine()) != null) {
everything.append(line);
}
String data = everything.toString();
data = data.trim();
System.out.println(data);
System.out.println(getPatternFromString(startPattern,endPattern, data));
leBuffer1.close();
} catch (FileNotFoundException exception) {
System.out.println("File not found");
}
}
}

How to correctly identify words when reading from a file with java Scanner?

I'm trying to do an exercise where I need to create a class to read the words from a .txt put the words in an HashSet. The thing is, if the text read "I am Daniel, Daniel I am." I'll have a word for "am" , "am." and "Daniel," and "Daniel". How do I fix this?
Here's my code. (I tried to use regex, but I'm getting an exception):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
public class WordCount {
public static void main(String[] args) {
try {
File file = new File(args[0]);
HashSet<String> set = readFromFile(file);
set.forEach(word -> System.out.println(word));
}
catch(FileNotFoundException e) {
System.err.println("File Not Found!");
}
}
private static HashSet<String> readFromFile(File file) throws FileNotFoundException {
HashSet<String> set = new HashSet<String>();
Scanner scanner = new Scanner(file);
while(scanner.hasNext()) {
String s = scanner.next("[a-zA-Z]");
set.add(s.toUpperCase());
}
scanner.close();
return set;
}
}
Error is thrown when the Scanner try to read a string not matching with the regex.
String s = scanner.next("[a-zA-Z]");
Instead of passing the regex in the Scanner. Read the word and remove the special characters as shown below.
String s = scanner.next();
s = s.replaceAll("[^a-zA-Z]", "");

How to import an online CSV file into Java and use each column as a variable?

I am trying to import a CSV file online which contains 6 fields. I am trying to import from a web link. I am able to download the file and use the file name as well. What I am trying to do is to read the data from the file and output it to my program.
So far I have this:
public class Element {
public static final String CSV_FILE_URL = "http://www.google.com/File.csv"; //Actual URl not published
public static void main(String[] args) throws IOException {
URL url = new URL(CSV_FILE_URL);
Scanner input =
new Scanner(url.openConnection().getInputStream());}
int number ;
String symbol;
String name;
int group;
int period;
double weight;
It might be a good idea to not use a Scanner but read the file line based, transform the lines into elements and then work on these like this:
public static void main(String[] args) {
try {
URL url = new URL("http://www.google.com/File.csv");
try(InputStream in = url.openStream();
InputStreamReader inr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(inr)) {
String line = br.readLine();
while(line != null) {
//Best case: no String separation, no ; contained in data items. If not
//you need some other way to split this
String[] elements = line.split(";");
//Deal with that one line
//Get next line
line = br.readLine();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

Need help creating an array that reads and writes a .txt and lists words in alphabetical orders

I just started to code a while back and I'm in the process of dealing with arrays on my own, I understand them in theory but I need some help when it comes to getting practical. I asked my instructor to give me a couple of practices problems and he gave me the following.
using this as your main:
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras( "words.txt" );
JOptionPane.showMessageDialog(null, datos );
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
(its in spanish so bear with me) create a class named DatosPalabras and words.txt and make sure your code can:
Read and display words.txt
Display the words in "words.txt" in alphabetical order
I really appreciate the help, I'm a bit stumped but I'm curious to know how I can accomplish this. Thank you!
EDIT:
public class DatosPalabras {
public DatosPalabras(String string) {
// read and display the content of words.txt
}
public void sort() {
// need info on what to use in order to sort words instead of doubles and integers.
}
}
In this example I have 1 file named Q19505617.java. Java only allows you to have 1 public class per file. It is the class that defines the main method. So this example works only because the DatosPalabras class is contained in that file. If you need DatosPalabras to be its own class then put the DatosPalabras in its own file named DatosPalabras.java and change the class signature to be public class DatosPalabras.
import java.io.InputStream;
import java.util.Arrays;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Q19505617 {
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras("words.txt");
JOptionPane.showMessageDialog(null, datos);
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
}
class DatosPalabras {
private String[] lines;
public DatosPalabras(String filename) {
lines = new String[1];
int lineCounter = 0;
InputStream in = Q19505617.class.getResourceAsStream(filename);
Scanner scanner = new Scanner(in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
if(lineCounter == lines.length) {
lines = Arrays.copyOf(lines, lines.length * 2);
}
lines[lineCounter] = line;
lineCounter++;
}
}
public void sort() {
// put your real sort algorithm here. until then use this:
}
public String toString() {
StringBuilder b = new StringBuilder();
for (String line : lines) {
b.append(line).append("\n");
}
return b.toString();
}
}
You can create a reading Array like this:
String[] Array = new String[number of lines in you txt file];
int i = 0;
// Selecting the txt file
File theFile = new File("bla.txt");
//Creating a scanner to read the file
scan = new Scanner(theFile);
//Reading all the words from the txt file
while (scan.hasNextLine()) {
line = scan.nextLine();
Array[i] = line; // gets all the lines
i++;
Then you create a method for sorting.

Simultaneous searching of multiple words in an external file(Java)

The program that I am trying to create is a program that takes words from a user defined file, saves those words as variables and then searches a different user defined file for those words, outputting there location.
The program works up to and including the point where the program takes the words and saves them as variables. The problem with the program is that the search method returns a null result. My main suspicions are that the code in the search method is incompatible with the code in the read method, or that the 2 methods aren't running simultaneously.
The search method is in the searching class and the read method is in the reading class.
Here is my code (Containing all 3 of my classes), please excuse all of the imports.
This is the first class:
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Combination{
public static void main(String[] args) throws FileNotFoundException{
Scanner userInput = new Scanner(System.in);
Reading ReadingObject = new Reading();
System.out.println("Please enter the file that you wish to open");
String temp = userInput.nextLine();
ReadingObject.setFileName(temp);
ReadingObject.read();
Scanner searchForWord = new Scanner(System.in);
Searching SearchingObject = new Searching();
System.out.println("Please enter the file that you would like to search for these words in");
String temp1 = searchForWord.nextLine();
SearchingObject.setFileName(temp1);
SearchingObject.search();
}
}
This is the second class:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
class Reading {
private String file;
public void setFileName(String fileName){
file = fileName;
}
public String getFileName(){
return file;
}
public void read(){
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
//Read the file line by line
while((strLine = br.readLine()) != null){
// \\s+ means any number of whitespaces between tokens
String [] tokens = strLine.split("\\s+");
String [] words = tokens;
for(String word : words){
System.out.print(word);
System.out.print(" ");
Searching SearchingObject = new Searching();
SearchingObject.setWord(word);
}
System.out.print("\n");
}
in.close();
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
This is the third class:
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Searching {
private String file1;
public void setFileName(String fileName){
file1 = fileName;
}
public String getFileName(){
return file1;
}
private String word1;
public void setWord(String wordName){
word1 = wordName;
}
public String getWord(){
return word1;
}
public void search() throws FileNotFoundException{
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
while((strLine = br.readLine()) != null){
Pattern p = Pattern.compile(getWord());
Matcher m = p.matcher(strLine);
int start = 0;
while (m.find(start)) {
System.out.printf("Word found: %s at index %d to %d.%n", m.group(), m.start(), m.end());
start = m.end();
}
}
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
Any help will be greatly appreciated.
Regards
Your code is hard to read. Your reading class does not only read; it also searches. You should call it something that reflects its intended use. However, it forgets to tell its searching object where to search, and does not pass the reference to this object to anyone else. In this snippet
for (String word : words) {
System.out.print(word);
System.out.print(" ");
searching searchingObject = new searching();
searchingObject.setWord(word);
}
you are essentially not doing anything. The reference to searchingObject is lost forever.
Your reading class should keep an ArrayList of words to be searched for in the searching, instead of instancing searching objects.
Your searching class should take, as a constructor parameter, one of these ArrayLists -- and convert it into a single regex, which is much more efficient than reading the file once per word to search for. You can search for "a", "b" and "c" using the single regular expression "a|b|c". Works with longer words, too. Escape them first to avoid problems.
Oh, and please, please follow naming guidelines. Call your reading a TokenReader, and your searching a WordListSearcher...

Categories