Parsing CSV file on Java to extract String - java

On Java Ive make a simple program with search bar. Ive also a CSV File 'file.csv' that contains this:
"ID","FIRSTNAME","LASTNAME"
"JM1","Jean","Martial"
"AD1","Audrey","Dubois"
"BX1","Bertrand","Xavier"
I can open the file on Java with this line.
String file = "C:\\file.csv";
To verify if file exists I use this line.
if(new File(file).exists()) {
JOptionPane.showMessageDialog(frame, "Fichier ouvert succes");
}
Now I want to parse the file to extract AD1 and display true if exist or false if not exists. Ive declared Scanner for this, but i dont know how to setup for this.
Scanner scanner = null;
try {
scanner = new Scanner(new File(file));
scanner.useDelimiter(coma_delimiter);
while(scanner.hasNext()) {
String s1= scanner.next();
System.out.print(s1 +" ");
if(s1.equals(search_field.getText())) {
System.out.print("OKOK");
} else {
System.out.println("NOK");
}
}
} catch (FileNotFoundException fe) {
fe.printStackTrace();
} finally {
scanner.close();
}
Here the search_field is a JTextField.

You are not reading your file line by line. What you are actually supposed to do is get a line, split it, remove the double quotes and compare to your string. Or you can wrap your input string in a double quote and just compare with the string after splitting. For this try the following code:
Scanner scanner = null;
try {
scanner = new Scanner(new File(file));
String s1 = null;
String id= null;
String[] tempArr = null;
String searchStr = "\""+search_field.getText()+"\"";
System.out.print("searchStr = " + searchStr );
while(scanner.hasNext()) { // While there are more lines in file
s1= scanner.nextLine();
tempArr = s1.split(","); // use coma_delimiter instead coma_delimiter if coma_delimiter=","
id = (tempArr != null && tempArr.length > 0? tempArr[0] : null);
System.out.print("ID = " + id);
if(id != null && id.equals(searchStr)) {
System.out.print("OKOK");
break; // quit the loop searchStr is found
} else {
System.out.println("NOK");
}
}
} catch (FileNotFoundException fe) {
fe.printStackTrace();
} finally {
scanner.close();
}

You may want to use Apache Commons CSV instead as this is designed to work with csv file, straight from their page is the below example
Reader in = new FileReader("path/to/file.csv");
Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in);
for (CSVRecord record : records) {
String lastName = record.get("Last Name");
String firstName = record.get("First Name");
}
where "Last Name" and "First Name" are all column names.
This way you can clearly check on which column your string is.
Maven dependency below:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.5</version>
</dependency>

You could also use the stream API to process each line individually. It may also have methods that would make this more elegant than my answer.
final String ENCL = "\"";
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
Map<String, List<String>> ans = stream.map(s -> {
String[] split = s.split(",");
if(split.length > 2) {
for(int i = 0; i < split.length; ++i) {
if(split[i].length() >= 2) {
if(split[i].startsWith(ENCL)) {
split[i] = split[i].substring(1);
}
if(split[i].endsWith(ENCL)) {
split[i] = split[i].substring(0, split[i].length()-1);
}
}
}
}
return split;
})
.filter(s->s.length > 2)
.collect(Collectors.toMap(s -> s[0], s-> Arrays.asList(s[1], s[2])));
// do what you will with ans
return ans.containsKey("AD1");
}
catch(IOException ex) {
// do what you will
}

Related

Where do I place the return of a function in JAVA?

I'm trying to figure out how to make a function in JAVA that searches through a document line per line:
First I initialize the file and a reader, then convert each line to a string in an ArrayList; after that I try to check the ArrayList against a String to then return the position of the ArrayList as a string.
So for example I have a text containing:
1 - Somewhere over the rainbow
2 - Way up high.
Converted to ArrayList, if then searched for: "Somewhere"; then it should return the sentence "Somewhere over the rainbow";
Here is the code I tried; but it keeps returning 'null';
String FReadUtilString(String line) {
File file = new File(filepath);
ArrayList<String> lineReader = new ArrayList<String>();
System.out.println();
try {
Scanner sc = new Scanner(file);
String outputReader;
while (sc.hasNextLine()) {
lineReader.add(sc.nextLine());
}
sc.close();
for(int count = 0; count < lineReader.size(); count++) {
if(lineReader.get(count).contains(line)){outputReader = lineReader.get(count);}
}
} catch (Exception linereadeline) {
System.out.println(linereadeline);
}
return outputReader;
}
I refactor your code a bit, but I keep your logic, it should work for you:
String FReadUtilString(String line, String fileName){
File file = new File(fileName);
List<String> lineReader = new ArrayList<>();
String outputReader = "";
try (Scanner sc = new Scanner(file))
{
while (sc.hasNextLine()) {
lineReader.add(sc.nextLine());
}
for (int count = 0; count < lineReader.size(); count++){
if (lineReader.get(count).contains(line)){
outputReader = lineReader.get(count);
}
}
}
catch (Exception linereadeline) {
System.out.println(linereadeline);
}
return outputReader;
}
NOTE: I used the try-with-resource statement to ensure the closing of the Scanner.
A more succinct version:
String fReadUtilString(String line, String fileName) {
try (Stream<String> lines = Files.lines(Paths.get(fileName))) {
return lines.filter(l -> l.contains(line)).findFirst();
}
catch (Exception linereadeline) {
System.out.println(linereadeline); // or just let the exception propagate
}
}

Reading text file variables and updated assigned values

I have a text file which has text as follows:
emVersion = "1.32.4.0";
ecdbVersion = "1.8.9.6";
ReleaseVersion = "2.3.2.0";
I want to update the version number by taking the input from a user if user enter the new value for emVersion as 1.32.5.0 then
emVersion in text file will be updated as emVersion = "1.32.5.0";
All this I have to do using java code. What I have done till now is reading text file line by line then in that searching the word emVersion if found the broken line into words and then replace the token 1.32.4.0 but it is not working because spaces are unequal in the file.
Code what i have written is :
public class UpdateVariable {
public static void main(String s[]){
String replace = "1.5.6";
String UIreplace = "\""+replace+"\"";
File file =new File("C:\\Users\\310256803\\Downloads\\setup.rul");
Scanner in = null;
try {
in = new Scanner(file);
while(in.hasNext())
{
String line=in.nextLine();
if(line.contains("svEPDBVersion"))
{
String [] tokens = line.split("\\s+");
String var_1 = tokens[0];
String var_2 = tokens[1];
String var_3 = tokens[2];
String var_4 = tokens[3];
String OldVersion = var_3;
String NewVersion = UIreplace;
try{
String content = IOUtils.toString(new FileInputStream(file), StandardCharsets.UTF_8);
content = content.replaceAll(OldVersion, NewVersion);
IOUtils.write(content, new FileOutputStream(file), StandardCharsets.UTF_8);
} catch (IOException e) {
}
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//---this code changes each version's values but the is a option to keep the old value.
Scanner in = new Scanner(System.in);
File file = new File("versions.txt");
ArrayList<String> data = new ArrayList<>();
String[] arr =
{
"emVersion", "ecdbVersion", "releaseVersion"
};
String line = "";
String userInput = "";
try (BufferedReader br = new BufferedReader(new FileReader(file));)
{
while ((line = br.readLine()) != null)
{
data.add(line);
}
for (int i = 0; i < arr.length; i++)
{
System.out.println("Please enter new " + arr[i] + " number or (s) to keep the old value.");
userInput = in.nextLine();
line = data.get(i);
String version = line.substring(0, line.indexOf(" "));
if (arr[i].equalsIgnoreCase(version))
{
arr[i] = line.replace(line.subSequence(line.indexOf("= "), line.indexOf(";")), "= \"" + userInput + "\"");
}
if (userInput.equalsIgnoreCase("s"))
{
arr[i] = line;
}
}
PrintWriter printWriter = new PrintWriter(new FileWriter(file, false));
printWriter.println(arr[0]);
printWriter.println(arr[1]);
printWriter.println(arr[2]);
printWriter.close();
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage());
}
Use regular expression eg:- line.trim().split("\s*=\s*"); . If it does not work please let me know , i will provide you complete solution.

Need help parsing a csv file and gathering the information together

The csv file I am trying to parse contains various samples with several lines per sample. For example, there are 10 lines with the same sample name "S1" and I need to get the CT value from each line. I am trying to combine the CT values (differentiated by the Target Name) to create a Sample class for each sample. I am able to parse the file, but I am having a hard time getting it to loop through and gather the right data.
The constructor for my Sample class has 11 parameters, one for the sample name and 10 for the CT values.
After thinking about it for a long time I tried gathering all of the information I need in an ArrayList of String arrays. This didn't help too much because I now don't know how to gather the information together to create and instance of my Sample class. Here's what I tried:
public void parseCSV(){
String line = "";
String csvSplitBy = ",";
try
{
Scanner scanner = new Scanner(new FileReader("/Users/Neema/Desktop/testData.csv"));
String[] data;
while (scanner.hasNextLine())
{
line = scanner.nextLine();
data = line.split(csvSplitBy);
if (data.length > 0 && data[0].equals("Well"))
{
while (scanner.hasNextLine())
{
line = scanner.nextLine();
data = line.split(csvSplitBy);
if (data.length > 4)
{
String sampleName = data[3];
String dataType = data[4];
String ctValue = data[11];
String[] gatheredData = {sampleName, dataType, ctValue};
parsedData.add(gatheredData);
}
}
}
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Here is the csv file, testData2
Thanks for any help!
I think I understand. What you need is a Sample Factory.
class SampleFactory {
String sampleName;
List<TargetAndValue> sampleList;
SampleFactory(String sampleName)
{
this.sampleName = sampleName;
}
class TargetAndValue{
String dataType;
String ctValue;
TargetAndValue(dataType, ctValue)
{
this.dataType = dataType;
this.ctValue = ctValue;
}
}
void addCtValue(dataType, ctValue) { //Instantiate a new TargetAndValue class }
Sample build(){ //Construct your Sample here }
}
Than what you need is a list of SampleFactories. As you parse each line you search for the SampleFactory that has the right sampleName, and add your data point. Once you have parsed everything use your factory to spit out your Sample objects.
Try it with a map. For example
public void parseCSV(){
String line = "";
String csvSplitBy = ",";
Map<String,List<String>> mapofSamples = new TreeMap<>(); // import java.util.Map; import java.util.TreeMap;
try
{
Scanner scanner = new Scanner(new FileReader("/Users/Neema/Desktop/testData.csv"));
String[] data;
while (scanner.hasNextLine())
{
line = scanner.nextLine();
data = line.split(csvSplitBy);
if (data.length > 0 && data[0].equals("Well"))
{
while (scanner.hasNextLine())
{
line = scanner.nextLine();
data = line.split(csvSplitBy);
if (data.length > 4)
{
if(!mapofSamples.containsKey(data[3])){ // if the map does not already contain the sample name add this name and a list with the value
mapofSamples.put(data[3],new ArrayList(){{add(data[11]);}} );
}
else{
mapofSamples.get(data[3]).add(data[11]); // else just add the value to the corresponding sample names value list
}
}
}
}
}
for(String key: mapofSamples.keySet()){ // check if it prints the right keys and values
System.out.println("sample :" + key);
System.out.println("values :" + mapofSamples.get(key));
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}

How to split strings into columns

I have a list of Strings in single column. I want to make three columns from these string and then print the ouput to another file. How do I do this?
Here is what I've tried so far:
ArrayList<String> list=new ArrayList<String>();
File file = new File("f://file.txt");
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
My input data:
City
Gsk
Relocation
sripallu
here
jrajesh
gurgaon
unitech
StatisticsThreads
WizOty
LTDParsvnathK
Quotesby
newest
PMaashuktr
My expected output:
City Gsk Relocation
sripallu here jrajesh
gurgaon unitech StatisticsThreads
WizOty LTDParsvnathK Quotesby
newest PMaashuktr Loans
.
.
.
.
.
.
.
You can structured your requirement in class like Output and make a list of Output.
public class Output{
private String str1;
private String str2;
private String str3;
<geter & setter method>
}
...
ArrayList<Output> list=new ArrayList<Output>();
int i=-1; Output op =null;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();i = ++i%3;
if(i==0){
op = new Output();
op.setStr1(line);
}else if(i==1)
op.setStr2(line);
else
op.setStr3(line);
}
I took your code and modified it a little:
File file = new File("f://file.txt");
try {
Scanner scanner = new Scanner(file);
int itemsOnRow = 0;
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
System.out.print (line + " ");
itemsOnRow++;
if (itemsOnRow == 3)
{
itemsOnRow = 0;
System.out.println ();
}
}
scanner.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
You should actually try to implement it next time. If you fail but post the code that you wrote, then it's easier for the people here to help you.

importing a text file

any way easier to do this??
i'm trying to import a file which is four lines:
name
phone
mobile
address
I'm using:
public void importContacts() {
try {
BufferedReader infoReader = new BufferedReader(new FileReader(
"../files/example.txt"));
int i = 0;
String loadContacts;
while ((loadContacts = infoReader.readLine()) != null) {
temp.add(loadContacts);
i++;
}
int a = 0;
int b = 0;
for (a = 0, b = 0; a < temp.size(); a++, b++) {
if (b == 4) {
b = 0;
}
if (b == 0) {
Name.add(temp.get(a));
}
if (b == 1) {
Phone.add(temp.get(a));
}
if (b == 2) {
Mobile.add(temp.get(a));
}
if (b == 3) {
Address.add(temp.get(a));
}
}
}
catch (IOException ioe) {
JOptionPane.showMessageDialog(null, ioe.getMessage());
}
txtName.setText(Name.get(index));
txtPhone.setText(Phone.get(index));
txtMobile.setText(Mobile.get(index));
txtAddress.setText(Address.get(index));
}
is their an easier way? looks long winded!
You can use the Scanner Class.
Scanner s = new Scanner(new File("input.txt"));
name = s.nextLine();
phone = s.nextLine();
mobile = s.nextLine();
address = s.nextLine();
Apache Fileutils readFileToString() or readLines() makes the code more clean.
import org.apache.commons.io.FileUtils;
...
File file = new File("foobar.txt");
try
{
List<String> data = FileUtils.readLines(file);
// Iterate the result to print each line of the file.
Iterator<String> iter = data.iterator();
while(iter.hasNext()) {
Name.add(iter.next());
if (iter.hasNext()) {
Phone.add(iter.next());
}
if (iter.hasNext()) {
Mobile.add(iter.next());
}
if (iter.hasNext()) {
Address.add(iter.next());
}
}
} catch (IOException e)
{
e.printStackTrace();
}
You could even make it a bit shorter by using a construction like
if (iter.hasNext()) Phone.add(iter.next());
but personally I feel that discarding braces makes code more error-prone. You could put it on one line, though.
Create a data object representing your set of data. With the new object, take in a string and parse it locally in the new object.
Driver Class:
readInFromFile
EntityClass
EntityClass(String) < calls the parse method
get[data elements]
parseFromString(String info) <- this is responsible for all of your reading
The "readFromFile" method will turn into:
....
while ((String line= reader.readLine) != null) {
list.add(new Entity(line));
}
BufferedReader infoReader = new BufferedReader(new FileReader("../files/example.txt"));
String loadContacts;
List<People> list = new ArrayList<People>();
while ((loadContacts = infoReader.readLine()) != null) {
String[] singleContact = loadContacts.split(REGEXP_FOR_SPLIT_VALUES);
People p = new People();
p.setName(singleContact[0]);
p.setPhone(singleContact[1]);
p.setMobile(singleContact[2]);
p.setAddress(singleContact[3]);
list.add(p);
}
How about this?
while(infoReader.hasNext()) {
Name.add(infoReader.readLine());
Phone.add(infoReader.readLine());
Mobile.add(infoReader.readLine());
Address.add(infoReader.readLine());
}
although I'd prefer changing the Name, Phone etc classes to be one class representing one contact.
Here's how I would do it, using the new Scanner class to read easily and take care of IOExceptions, using the ClassLoader to find the file, and using a simple #Data class to store the data.
public void importContacts() {
Scanner scanner = new Scanner(ClassLoader.getSystemClassLoader().getResourceAsStream("example.txt"));
List<Contact> list = Lists.newArrayList();
while(scanner.hasNext()) {
list.add(new Contact(
scanner.nextLine(),
scanner.nextLine(),
scanner.nextLine(),
scanner.nextLine()
));
}
Contact c = list.get(index);
txtName.setText(c.getName());
txtAddress.setText(c.getAddress());
txtPhone.setText(c.getPhone());
txtMobile.setText(c.getMobile());
}
private static #Data class Contact {
private final String name, phone, mobile, address;
}
If the file will only ever contain one contact and you have control over the format of the source text file you could reformat it like a properties file:
name=value
Then you'd read it in as a properties file (see ResourceBundle), which ends up being simple:
Mobile.add(properties.getProperty("mobile"))
Why not just:
public String readLine(BufferedReader pReader) {
try {
return pReader.readLine();
} catch(IOException IOE) {
/* Not a very good practice but let say "We don't care!" */
// Return null if the line is not there (like there was no 4 lines in the file)
return null;
}
}
public void importContacts() {
try {
BufferedReader infoReader = new BufferedReader(new FileReader("../files/example.txt"));
txtName .setText(readLine(infoReader));
txtPhone .setText(readLine(infoReader));
txtMobile .setText(readLine(infoReader));
txtAddress.setText(readLine(infoReader));
} catch (IOException ioe) {
JOptionPane.showMessageDialog(null, ioe.getMessage());
}
}
Hope this helps.

Categories

Resources