Reading filepath from properties file - java

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;
}

Related

check if the word in the set equals word in outside file

I have a set of words and an outside file.
I want to check if a word in the set is already present in the outside file. If the word is already in the file, then do nothing, if the word is not in the outside file already, then add it to the outside file.
This is the code I have written:
public static void toFile(Set<String> vocab, String filename)
{
try
{
for(String vocabWord : vocab)
{
File file = new File(filename);
Scanner sc2 = new Scanner(file);
while(sc2.hasNextLine())
{
String docWord = sc2.nextLine();
if (!(vocabWord.equals(docWord)))
{
FileWriter myWriter = new FileWriter(filename, true);
PrintWriter printWriter = new PrintWriter(myWriter);
printWriter.println(vocabWord);
printWriter.close();
}
else
break;
}
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
I am using three different text documents to test it, have the line "test file one", "test file two", and "test file three".
The output I was expecting was: "test file three" (it is connected with a stop list which one and two are part of, and has been working)
However, when I run it, either with only one of the files or all three consecutively, the file always comes out empty.
I tried changing up things in the method, but nothing has worked, I either get an infinite loop or nothing in the outside file.
I am not sure what I am missing... I would really appreciate any help.
I tried this and added some comments for explanation. I have tested on local machine and it works
public static void toFile(Set<String> vocab, String filename) {
try {
for(String vocabWord : vocab) {
//task for each String in our Set
File file = new File(filename);
Scanner sc2 = new Scanner(file);
boolean exists = false;//lets say it doesn't exist
while(sc2.hasNextLine()) {
//task for each line in the text
//search the whole file first for the word
String docWord = sc2.nextLine();
if (docWord.equals(vocabWord)){
exists = true;
break;
}
}
if (!exists) {
//add the vocabWord only if it doesnt exists
FileWriter myWriter = new FileWriter(filename, true);
PrintWriter printWriter = new PrintWriter(myWriter);
printWriter.println(vocabWord);
printWriter.close();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
To append the missing vocabulary in order of vocab, you can reduce the file operations
as such:
public static void toFile(Set<String> vocab, String filename) {
try {
Charset charset = Charset.defaultCharset();
Path path = Paths.get(filename);
Set<String> existing = Files.lines(path, charset)
.collect(Collectors.toSet());
if (!existing.isEmpty()) {
try (BufferedWriter bw = Files.newBufferedWriter(path, charset,
StandardOpenOption.APPEND);
PrintWriter printWriter = new PrintWriter(bw)) {
vocab.stream()
.filter(word -> !existing.contains(word))
.forEach(word -> printWriter.println(word));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

Read specific property from a property file in a jar

I need to read the property "product.build.number" from the property file "version.properties" which lies at the root level of each of the jars. My naive approach is:
private static int getProductBuildNumber(File artefactFile) throws FileNotFoundException, IOException
{
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(
artefactFile)))
{
Set<String> possClasses = new HashSet<>();
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip
.getNextEntry())
{
if (!entry.isDirectory() && entry.getName().toLowerCase().equals(
"version.properties"))
{
List<String> lines = IOUtils.readLines(zip, (String) null);
for (String line : lines)
{
if (line.startsWith("product.build.number"))
{
String[] split = line.split("=");
if (split.length == 2)
{
return Integer.parseInt(split[1]);
}
}
}
}
}
}
throw new IOException("product.build.number not found.");
}
I guess there are more elegant and reliable ways. Any ideas?
Try something like (untested):
private static int getProductBuildNumber(Path artefactFilePath) throws IOException{
try(FileSystem zipFileSystem = FileSystems.newFileSystem(artefactFilePath, null)){
Path versionPropertiesPath = zipFileSystem.getPath("/version.properties");
Properties versionProperties = new Properties();
try (InputStream is = Files.newInputStream(versionPropertiesPath)){
versionProperties.load(is);
}
return Integer.parseInt(versionProperties.getProperty("product.build.number"));
}
}
You haven’t said whether the .jar files are are in your classpath.
If they are in your classpath, you should be using Class.getResourceAsStream to read the entry:
try (InputStream propStream = getClass().getResourceAsStream("/version.properties")) {
// ...
}
If they .jar files are not in your classpath, you should create a jar: URL from the file. The format of such a URL is described in the JarURLConnection documentation.
Note that java.io.File is obsolete, and you should always use Path instead:
private static int getProductBuildNumber(Path artefactFile)
throws IOException {
URL propsURL = new URL("jar:" + artefactFile.toUri() + "!/version.properties");
try (InputStream propStream = propsURL.openStream()) {
// ...
}
}
Regardless of the data’s location, you should always use the Properties class to read properties. (Parsing a properties file yourself means you have to account for comments, Unicode escapes, continuation lines, and all possible name/value separators.)
Properties props = new Properties();
try (InputStream propStream = getClass().getResourceAsStream("/version.properties")) {
props.load(propStream);
}
int buildNumber = Integer.parseInt(
props.getProperty("product.build.number"));

how to write in properties file without deleting old values

I want to write in properties file without removing earlier written values in file.
for Eg there is value in properties file
token = tokengenerated
Now when I again set new value like
token1 = tokensnew
Then the properties file should show
token = tokengenerated
token1 = tokensnew
Pass true as a second argument to FileWriter to turn on "append" mode.
fout = new FileWriter("filename.txt", true);
FileWriter usage reference
You should read file and update it through properties and streams.
below is the code snippet is help you.
public class ReadAndWriteProperties {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
String propertiesFileName = "config.properties";
File f = new File(propertiesFileName);
InputStream input = new FileInputStream(f);
if (input != null) {
props.load(input);
props.setProperty("token2", "tokensnew");
OutputStream out = new FileOutputStream(f);
props.store(out, "save");
}
}
}
You must read the file (var1), then add your content to the var1 and then write the var1 to the file.

Storing values in different variables by reading a file

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();
}
}

Somehow this method deletes my file content but for no apparent reason

If I didn't miss anything you should be able to run this code, just need a trace.log file in your project root folder.
I don't get what's happening. I just declare some readers / writers and try to read from the file. I get an instant null and the file seems to be empty. WHY?!
import java.io.*;
public class StubLogHandler {
private String name = "";
private String path = "";
public StubLogHandler (String filePath, String fileName) {
this.name = fileName;
this.path = filePath;
}
// THIS IS THE PESCKY BUGGER
public void testReadWrite() {
this.fixPath();
File file = new File (this.path+this.name);
try ( FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter(file);
BufferedReader reader = new BufferedReader(fileReader);
BufferedWriter writer = new BufferedWriter(fileWriter);) {
System.out.println("Works, I think.");
String line = "";
while (line != null) {
line = reader.readLine();
System.out.println(line);
// Should get a coupl'a lines, instead I get instant null
// Before you ask, no, the file is not initially empty
}
} catch (FileNotFoundException fnfe) {
System.out.println("File Not Found");
} catch (IOException ioe) {
System.out.println("Could not read or write to file");
}
}
private void fixPath () {
if (this.path.isEmpty())
return;
char lastChar = this.path.charAt(this.path.length()-1);
if (lastChar != '\\')
this.path += "\\"; // In case user forgets the final '\'
}
public String getAbsolutePath() {
this.fixPath();
return new File(this.path+this.name).getAbsolutePath();
}
}
public class Start {
public static void main (String[] args) {
Start.testStuff();
}
private static void testStuff() {
StubLogHandler log = new StubLogHandler("","trace.log");
System.out.println(log.getPath()+log.getName());
System.out.println(log.getAbsolutePath());
log.testReadWrite();
}
}
EDIT
Output:
trace.log
D:\Personal\Java\Workspaces\Default\Practice\trace.log
Works, I think.
null
Creating that writer:
try ( FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter(file); // here
will immediately truncate that file in preparation for writing. e.g.
File x = new File("X");
FileWriter fw = new FileWriter(x);
will immediately erase the contents of the pre-existing file X
Normal reading and separately writing to the same file does not work.
FileReader and FileWriter are already buffered I believe. I personally do not use them, as they use the default platform encoding, which is gives unportable data.
And then the end of file is indicated by readLine returning null, hence do:
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println(line);
// Should get a coupl'a lines, instead I get instant null
// Before you ask, no, the file is not initially empty
}
Maybe be you want do something like:
Path fpath = Paths.get(this.path+this.name);
List<String> lines = Files.readAllLines(fpath, StandardCharsets.UTF_8);
... process the lines
Files.write(fpath, lines, StandardCharsets.UTF_8);

Categories

Resources