Storing values in different variables by reading a file - java

i'm a beginner at java and still learning so please excuse my question if it sounds stupid.
i've been stuck on a straight forward problem i was given:
i'm supposed to read a text file and store the values of the text file in different variables. my text file looks like:
foo.txt
Directory_path=C:\University
school_name=SyracuseUni
i want to store the directory path and school_name in a new variable say
var_one = C:\University
and var_two = SyracuseUni
I was able to split it but in a single string.
public static void main(String[] args) throws IOException {
try {
BufferedReader br = new BufferedReader(new FileReader("C:\\foo.txt"));
String strLine = null;
String var_one = null;
String var_two = null;
while ((strLine = br.readLine()) != null) {
String[] parts = strLine.split("=");
String parameter = parts[1];
System.out.println(parameter);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
this gives me an output like this which isn't how i want it:
C:\University
SyracuseUni
i will appreciate if anyone can guide me towards the right approach. thanks all.

There is already a simple way to deal with such files using java.util.Properties class. This could be an overkill if you are simply trying to learn how to read a file.
public static void main(String[] args) {
String myVar1 = null;
String myVar2 = null;
Properties prop = new Properties();
InputStream input = null;
try (FileInputStream input = new FileInputStream("pathToYourFile")) {
prop.load(input);
myVar1 = prop.getProperty("Directory_path");
myVar2 = prop.getProperty("school_name");
} catch (IOException ex) {
//Handle exception
}
}

Something simple would be using Java Properties. You could also store values in a map. If you really insisted on filling two separate varibles, you could always count how many lines you've went across in your while loop and use switch/case to determine which variable to fill.
public static void main(String[] args) throws IOException {
try {
BufferedReader br = new BufferedReader(new FileReader("C:\\foo.txt"));
String strLine = null;
HashMap<String, String> map = new HashMap<String, String>();
while ((strLine = br.readLine()) != null) {
String[] parts = strLine.split("=");
map.put(parts[0], parts[1]);
}
for (Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " = " + value);
}
}
catch (IOException e) {
e.printStackTrace();
}
}

Related

Expanding abbreviations from .csv file

So I have this task to do, I need to expand text abbreviations from the message into their full form from the .csv file, I loaded that file into HashMap, with keys as abbreviations and values as full forms. There is a loop to iterate through the keys and if statement which replaces abbreviation to full form if it finds any. I kind of figured it out and it is working as it should but I want to send this changed String (with abbreviations expanded) somewhere else out of if statement to save the full message to the file. I know that this String exists only in this if statement but maybe there is another way of doing it? Or maybe I'm doing something wrong? I became a bit rusty with Java so maybe there is a simple explanation that I don't know about. Here is the code I have :
public class AbbreviationExpander {
static void AbrExpander(String messageBody) {
//read the .csv file
String csvFile = "textwords.csv";
String line = "";
String cvsSplitBy = ",";
String bodyOut = messageBody;
HashMap<String, String> list = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] abbreviatonFile = line.split(cvsSplitBy);
//load the read data into the hashmap
list.put(abbreviatonFile[0], abbreviatonFile[1]);
}
for (String key : list.keySet()) {
//if any abbreviations found then replace them with expanded version
if (messageBody.contains(key)) {
bodyOut = bodyOut.replace(key, key + "<" + list.get(key).toLowerCase() + ">");
try {
File file = new File("SMS message" + System.currentTimeMillis() + ".txt");
FileWriter myWriter = new FileWriter(file);
myWriter.write(bodyOut);
myWriter.close();
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
} catch (IOException f) {
f.printStackTrace();
}
}
}
Not sure I understood well your problem. But I think you should separate the different steps in your code.
I mean your try-catch block that writes your output should be outside the for-loop and outside the reading try-catch. And your for-loop should be outside your reading try-catch.
public class AbbreviationExpander {
static void AbrExpander(String messageBody) {
String csvFile = "textwords.csv";
String line = "";
String cvsSplitBy = ",";
String bodyOut = messageBody;
HashMap<String, String> list = new HashMap<>();
//read the .csv file
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] abbreviatonFile = line.split(cvsSplitBy);
//load the read data into the hashmap
list.put(abbreviatonFile[0], abbreviatonFile[1]);
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
//if any abbreviations found then replace them with expanded version
for (String key : list.keySet()) {
if (messageBody.contains(key)) {
bodyOut = bodyOut.replace(key, key + "<" + list.get(key).toLowerCase() + ">");
}
}
//output the result in your file
try {
File file = new File("SMS message" + System.currentTimeMillis() + ".txt");
FileWriter myWriter = new FileWriter(file);
myWriter.write(bodyOut);
myWriter.close();
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}

Reading and splitting data from a text file

So I have a text file that looks like this...
4234
Bob
6858
Joe
I am trying to read the file with java and insert the data into an array. I want to separate the data by that empty line (space). Here is the code that I have come up with to solve the issue, but I am not quite there.
public class Main {
public static void main(String[] args) {
// This name is used when saving the file
BufferedReader input;
String inputLine;
try {
input = new BufferedReader(new FileReader("test.txt"));
while ((inputLine = input.readLine()) != null) {
System.out.println(Arrays.toString(inputLine.split(" ")));
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(1);
}
}
}
The issue that I am coming across is that the output from the code above looks something like this
[4234]
[Bob]
[]
[6858]
[Joe]
The outcome that I would like to achieve, and for the life of me can't think of how to accomplish, is
[4234, Bob]
[6858, Joe]
I feel like with many things that it is a relatively simple code change; I am just not sure what that is.
You need:
2D array
Logic to keep track of where you are in the array position
If your Line is a Number/String
This sounds like hw :) so I wont be solving it, I will just help a bit.
String[][] myData = define your 2D array;
//You need to create a consumer. This is what will take the String line, figure out where to put it into your 2D array.
Consumer<String> processLine = (line) -> {
if(StringUtils.isNumeric(line)){
//Put into array[counter][1]
}
else{
//its a String
//Put into array[counter][0]
}
};
The below try/catch, Opens a File, Reads its Lines, and goes over each one in order (forEachOrdered), ignoring all empty lines, and send it to your processLine consumer.
try (Stream<String> lines = Files.lines(Paths.get("C:/example.txt"), Charset.defaultCharset())) {
lines.filter(line -> !line.isEmpty()).forEachOrdered(processLine);
}
catch (Exception e){
//Handle Exception
}
Used Apache StringUtils http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
IF you dont want to use any external Libs. You can probably do
Integer.parseInt(line) <-- If that throws an exception, its not a number
Your way of reading the file is not most convenient, in this case.. Scanner would have eased all this work; however, if you insist, that you want to use BufferedReader and FileReader, it's going to be a bit verbose, boilerplate and even ugly code, something like this:
public class Main {
public static void main(String[] args) {
// This name is used when saving the file
BufferedReader input;
String inputLine;
String answer = "";
try {
input = new BufferedReader(new FileReader("path\\to\\your\\test.txt"));
while ((inputLine = input.readLine()) != null) {
answer = answer + "[" + inputLine + ", ";
while ((inputLine = input.readLine()) != null && !inputLine.equals("")) {
answer += inputLine;
}
answer += "]";
System.out.println(answer);
answer = "";
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(1);
}
}
}
This code, with test.txt containing:
4234
Bob
6858
Joe
4234
John
5352
Martin
will output:
[4234, Bob]
[6858, Joe]
[4234, John]
[5352, Martin]
I don't know if it's an actual requirement for you to use arrays of strings, but the better way in the long run is to create a class.
class Person {
public String id;
public String name;
public String toString() { return String.format("[%s, %s]", id, name); }
}
(note: It's a bad idea to actually make the fields public, but this makes the code shorter. You should probably use getters and setters).
Now you can create Persons while reading the file.
List<Person> allInFile = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader("path\\to\\your\\test.txt"))) {
String line = reader.readLine();
while (line != null) {
line = line.trim();
// ignore empty lines
if (line.length() == 0) {
continue;
}
// this is an id; create a person and assign id
Person person = new Person();
person.id = line;
// read consecutive field, which is the name
person.name = reader.readLine();
// add the person to the list
allInFile.add(person);
}
}
allInFile.forEach(System.out::println);
Lots of improvements to be done on this, but the main point is to put the two data points into a class.
Try with this code:
it work only when file contains number followed by name otherwise pair would be different format
pair : [number, string]
public static void main(String[] args) {
BufferedReader input;
String inputLine;
List<String> pair = new ArrayList<String>();
List<String> list = new ArrayList<String>();
try {
input = new BufferedReader(new FileReader("Test.txt"));
while ((inputLine = input.readLine()) != null) {
if (!inputLine.isEmpty()) {
pair.add(inputLine);
}
if (pair.size() == 2) {
list.add(pair.toString());
pair.clear();
}
}
for (String s : list) {
System.out.println(s);
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(1);
}
}
After looking at the answers posted by my fellow Stack Overflow members I figured out that there was a very simple way of solving this issue and that was by using Scanner rather than using BufferedReader. I am not sure why I didn't think of this before, but hindsight is 2020. Anyway, the code below is what I used to solve my issue.
public static void main(String[] args) {
ArrayList<String> test = new ArrayList<>();
File file = new File("test.txt");
try {
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
test.add(sc.next()); // The id
test.add(sc.next()); // The name
}
sc.close();
System.out.println(test.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
All this is doing is getting each line with the different data on it and is skipping the blank. From there it is adding it to an ArrayList for later processing. Remember K.I.S.S (Keep It Simple Stupid) no need to overcomplicate anything.

how to replace strings in a file by other strings in java

I have a file which every line contains strings like that :
usual,proper,complete,1,convenient,convenient,nonprob,recommended,recommend
I want to replace every word by such a code like that :
1000, 100, 110, 110, 111, 001, 111, 111, 1000
Here is the code that I used but it still incomplete :
public class Codage {
BufferedReader in;
public Codage() {
try {
in = new BufferedReader(new FileReader("nursery.txt"));
FileOutputStream fos2 = new FileOutputStream("nursery.txt");
DataOutputStream output = new DataOutputStream(fos2);
String str;
while (null != ((str = in.readLine()))) {
String delims = ",";
String[] tokens = str.split(delims);
int tokenCount = tokens.length;
for (int j = 0; j < tokenCount; j++) {
if (tokens[j].equals("usual")) {
tokens[j] = "1000";
output.writeChars(tokens[j]);
}
//continue the other cases
}
System.out.print(str);
}
in.close();
} catch (IOException e) {
System.out.println("There was a problem:" + e);
}
}
public static void main(String[] args) {
Codage c = new Codage();
}
}
My code replace the values incorrectly.
First of all, the code you wrote here is not working, because when you open an outputStream to the exact file you try read from, it will empty the source file and the statement in.readLine() always returns null. So if this is your real code maybe this is the problem.
I assume that you know you should separate the file you are opening to read from and the one you want to write into. That is, when you open the nursery.txt to read from, you should create an outputStream to a temp file called nursery.tmp in the same path, and after the process is finished, you can delete the nursery.txt and rename the nursery.tmp to nursery.txt.
Also if I were you, I wouldn't do the job using if-else structure. It seams that you have unique keys like:
usual, proper, complete, convenient, convenient, nonprob, recommended, recommend
So maybe it is more convenient to use a map structure to lookup the replacing value:
usual, proper, complete, convenient, convenient, nonprob, recommended, recommend, ...
1000, 100, 110, 110, 111, 001, 111, 111, ...
But these are just some guesses and you know how to manage your business logic.
After that part I think this is a better idea to create the output data as String lines and write them line by line to the nursery.tmp:
public class Codage {
private BufferedReader in;
private BufferedWriter out;
private HashMap<String, String> replacingValuesByKeys = new HashMap<String, String>();
public Codage() {
initialize();
}
private void initialize() {
// I assumed that you have rule that a key like "proper" always goes to "100"
// Initialize the map between keys and replacing values:
replacingValuesByKeys.put("usual", "1000");
replacingValuesByKeys.put("proper", "100");
replacingValuesByKeys.put("complete", "110");
replacingValuesByKeys.put("convenient", "110");
replacingValuesByKeys.put("nonprob", "111");
replacingValuesByKeys.put("recommended", "001");
replacingValuesByKeys.put("recommend", "1000");
}
public void doRelpacementInFile(){
try {
in = new BufferedReader(new FileReader("c:/nursery.txt"));
out = new BufferedWriter(new FileWriter("c:/nursery.tmp"));
String str = in.readLine();
while (null != str) {
Iterator<String> it = replacingValuesByKeys.keySet().iterator();
while(it.hasNext())
{
String toBeReplaced = it.next();
String replacementValue = replacingValuesByKeys.get(toBeReplaced);
// \\b is for word boundary, because you have both recommend and recommended
// and we do not want to replacing the [recommend] part of recommended.
str = str.replaceAll("\\b"+toBeReplaced+"\\b", replacementValue);
}
// Write the fully replaced line to the temp file:
out.append(str);
out.newLine();
// Do not forget to read the next line:
str = in.readLine();
}
} catch (IOException e) {
System.out.println("There was a problem:" + e);
} finally{
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
File f = new File("c:/nursery.txt");
f.delete();
File f2 = new File("c:/nursery.tmp");
f2.renameTo(new File("c:/nursery.txt"));
}
public static void main(String[] args) {
Codage c = new Codage();
c.doRelpacementInFile();
}
}
Hope this snippets would be helpful,
Good Luck.

Using a loop I want to find the value of a column from my CSV file java

Forgive me if this is a basic (or not very well explained) question, I am fairly new to Java and have been reading extensive material as well as trying to understand the relevant Javadoc but to no avail.
To give a brief background as to what I am trying to create, I have created a reader class which reads data in from a csv file (4 lines long) including fields such as Item ID, price, description etc. I have created a separate demo class that displays the details of this csv file (through creating an instance of my reader class) and am now trying to create a method that asks the user to input an Item ID that then displays the corresponding Item, based on the ID input by the user. The part I am stuck on is accessing specific rows/columns in a csv file and then comparing these with a given string (entered by the user which corresponds to a specific field in the csv file)
This is what I have come up with thus far:
input = new Scanner(System.in);
System.out.println("Enter a product code");
String prodC = input.next();
//Here I want to know if there is a way of accessing a field in a csv file
Any ideas would be greatly appreciated.
UPDATE
Thank you for quick responses, am currently reading through and seeing how I can try to implement the various techniques. In response to the comment asking about the file reader, this is how I have set that out:
public CatalogueReader(String filename) throws FileNotFoundException {
this.filename = filename;
this.catalogue = new Catalogue();
Scanner csvFile;
try {
csvFile = new Scanner(new File(filename));
} catch (FileNotFoundException fnf) {
throw new FileNotFoundException("File has not been found!");
}
csvFile.useDelimiter("\n");
boolean first = true;
String productCode;
double price;
String description;
double weight;
int rating;
String category;
boolean ageRestriction;
String csvRows;
while (csvFile.hasNextLine()) {
csvRows = csvFile.nextLine();
if (first) {
first = false;
continue;
}
System.out.println(csvRows);
String[] fields = csvRows.split(",");
productCode = (fields[0].trim());
price = Double.parseDouble(fields[1].trim());
description = fields[2].trim();
weight = Double.parseDouble(fields[3].trim());
rating = Integer.parseInt(fields[4].trim());
category = fields[5].trim();
ageRestriction = Boolean.parseBoolean(fields[6].trim());
catalogue.addAProduct(new Item(productCode, price, description, weight, rating, category, ageRestriction));
}
csvFile.close();
}
}
ok so for a CSV file like this:
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"
here is a sample of how to read using Java Native Libraries
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CSVReader {
public static void main(String[] args) {
CSVReader obj = new CSVReader();
obj.run();
}
public void run() {
String csvFile = YOURFILEPATHHERE ;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("Country [code= " + country[4]
+ " , name=" + country[5] + "]");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
does this help?
If you are just doing a single look-up and then exiting then just remember the String you are looking for. As you parse the lines compare to see if you have a match and if you do then return that line.
For repeated searches that would be very inefficient though. Assuming your data set is not too large for memory you would be better off parsing the file and putting it into a Map:
Map<String, Data> dataMap = new HashMap<>();
Parse the file, putting all the lines into the map
Then the lookup just becomes:
Data d = dataMap.get(lineKey);
If d is null then there is no matching line. If it not null then you have found your line.
You can create an array list of object. An object for each line in the CSV. Then search the array object with your search criteria.
User CSVReader framework to read the csv file. Sample code (not exactly what you want)
FileInputStream fis = new FileInputStream(file);
CSVReader reader = new CSVReader(new BufferedReader( new InputStreamReader(fis, "UTF-8" )));
ArrayList<String> row = new ArrayList<String>();
ArrayList<Entry> entries = new ArrayList<Entry>();
// a line = ID, Name, Price, Description
while (!reader.isEOF()) {
reader.readFields(row);
if( row.size() >= 4)
entries.add(new Entry(row.get(0), row.get(1), row.get(2), row.get(3)));
}
System.out.println("Size : "+entries);

Reading filepath from properties file

I'm trying to read a file from a filepath read from properties, but I keep getting FileNotFoundException (the file exists).
test.properties:
test.value = "src/main/resources/File.csv"
LoadProperties.java:
public class LoadProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties aProp = new Properties();
aProp.load(new FileInputStream("src/main/resources/test.properties")); // works
String filepath = aProp.getProperty("test.value");
System.out.println(filepath); // outputs: "src/main/resources/File.csv"
FileReader aReader = new FileReader("src/main/resources/File.csv"); // works
FileReader aReader2 = new FileReader(filepath); // java.io.FileNotFoundException
}
}
Why is this exception being thrown while the line above it works just fine?
How should I read a file from a path provided with properties?
You are not supposed to put " in your property file. Here Java sees it as :
String file = "\"src/main/resources/File.csv\"";
test.value =src/main/resources/File.csv
You don't need double quotes in properties file to represent a continuous string.
you can write own logic to read properties file, it does not matter whether single quotes or double quotes are there in the file path
String propertyFileLocation = "C:\a\b\c\abc.properties";
try
{
fileInputStream = new FileInputStream(propertyFileLocation);
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
properties = new Properties();
String currentLine = null;
String[] keyValueArray = null;
while ((currentLine = bufferedReader.readLine()) != null) {
if (!currentLine.trim().startsWith("#")) {
keyValueArray = currentLine.split("=");
if (keyValueArray.length > 1) {
properties.put(keyValueArray[0].trim(), keyValueArray[1].trim().replace("\\\\","\\"));
}
}
}
}
catch (Exception e)
{
return null;
}

Categories

Resources