Java: How do I access my properties file? - java

So I have a property file in my project. I need to access it.
Here's the tree structure:
+ Project Name
|--+ folder1
|--+ propertyfolder
|--+ file.properties
Or: Project/propertyfolder/file.properties
Here's what I've tried so far (one at a time, not all at once):
// error: java.io.File.<init>(Unknown Source)
File file = new File(System.getProperty("file.properties"));
File file = new File(System.getProperty("propertyfolder/file.properties"));
File file = new File(System.getProperty("propertyfolder\\file.properties"));
File file = new File(System.getProperty("../../propertyfolder/file.properties"));
And:
InputStream inputStream = getClass().getResourceAsStream("file.properties");
InputStream inputStream = getClass().getResourceAsStream("../../propertyfolder/file.properties");
InputStream inputStream = getClass().getResourceAsStream("propertyfolder/file.properties");
InputStream inputStream = getClass().getResourceAsStream("propertyfolder\\file.properties");
And all variations within getClass(), such as getClass().getClassLoader(), etc.
The error I'm getting is a NullReferenceException. It's not finding the file. How do I find it correctly?

(taken from comment to answer as OP suggested)
Just use File file = new File("propertyfolder/file.properties") but you do need to know where is java process working directory, if you cannot control it try an absolute path /c:/myapp/propertyfolder/file.properties.
You may also use /myapp/propertyfolder/file.properties path without C: disk letter to avoid windows-only mapping. You may use / path separator in Java apps works in Win,Linux,MacOSX. Watch out for text file encoding, use InputStreamReader to given an encoding parameter.
File file = new File("propertyfolder/file.properties");
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader reader = new BufferedReader(isr);
..read...
reader.close(); // this will close underlaying fileinputstream

Inorder to use getClass().resourceAsStream("file.properties") you need to make sure the file is there in the classpath.
That is if your Test.java file is compiled into bin/Test.class then make sure to have file.properties in the bin/ folder along with the Test.class
Otherwise you can use the Absolute Path, which is not advisable.

Did you set System properties to load file.properties from
1) Command line using -Dpropertyname=value OR
2) System.setProperty() API OR
3) System.load(fileName) API?
If you have n't done any one of them, do not use System.getProperty() to load file.properties file.
Assuming that you have not done above three, the best way to create file InputStream is
InputStream inputStream = getClass().getResourceAsStream("<file.properties path from classpath without />");

Properties extends Hashtable so, Each key and its corresponding value in the property list is a string.
Properties props = new Properties();
// File - Reads from Project Folder.
InputStream fileStream = new FileInputStream("applicationPATH.properties");
props.load(fileStream);
// Class Loader - Reades Form src Folder (Stand Alone application)
ClassLoader AppClassLoader = ReadPropertyFile.class.getClassLoader();
props.load(AppClassLoader.getResourceAsStream("classPATH.properties"));
for(String key : props.stringPropertyNames()) {
System.out.format("%s : %s \n", key, props.getProperty(key));
}
// Reads from src folder.
ResourceBundle rb = ResourceBundle.getBundle("resourcePATH");// resourcePATH.properties
Enumeration<String> keys = rb.getKeys();
while(keys.hasMoreElements()){
String key = keys.nextElement();
System.out.format(" %s = %s \n", key, rb.getString(key));
}
// Class Loader - WebApplication : src folder (or) /WEB-INF/classes/
ClassLoader WebappClassLoader = Thread.currentThread().getContextClassLoader();
props.load(WebappClassLoader.getResourceAsStream("webprops.properties"));
To read properties from specific folder. Construct path form ProjectName
InputStream fileStream = new FileInputStream("propertyfolder/file.properties");
If Key:value pairs specified in .txt file then,
public static void readTxtFile_KeyValues() throws IOException{
props.load(new FileReader("keyValue.txt") );
// Display all the values in the form of key value
for (String key : props.stringPropertyNames()) {
String value = props.getProperty(key);
System.out.println("Key = " + key + " \t Value = " + value);
}
props.clear();
}

Related

Java: fail to get the absolute path of a file

Below is my project like:
projectName
-package
- Util.java
- Test.json
In Util.java, I need to read the content from Test.json file and parse it.
Thus I use:
File currentfile = new File("");//get the current path
String absJsonPath = currentfile.getAbsolutePath() + "/Test.json";
While it did not work when I use a main method to test it. The thing is that the /src/package is lost in the obtained file path and I just got the path of the project.
And, when I deploy the project to weblogic server, I got another new error, the obtained current path is like:
.../DefaultDomain/.
I just want the file path in the file system, which is not related to the server.
What can I do for this? Thanks!
Put your file in resources folder and get it as following:
//Get file from resources folder
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("Test.json").getFile());
To read the content you can use following:
StringBuilder result = new StringBuilder("");
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
result.append(line).append("\n");
}
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
It's CanonicalPath() not Absolute. Check this out, let me know if it any helps.
Try this to get current path
String currentPath = System.getProperty("user.dir");
If you want to read a file in a specific package. You can use
File jsonFile = new File(getClass().getResource("/Test.json").getFile());

Cannot read files from resources folder

Final edit: now the code looks like this
InputStream is = getClass().getResourceAsStream("/static/master-key.txt");
String masterKey = null;
Scanner scanner = new Scanner(is);
masterKey = scanner.nextLine();
System.out.println("the master key is " + masterKey);
Original post
I have a problem when reading txt file from resources folder.
This what project structure looks like:
projStructure
When I invoke the following code
System.out.println(getClass().getClassLoader().getResource("static/master-key.txt").getPath());
File mkFile = new File(getClass().getClassLoader().getResource("static/master-key.txt").getPath());
this what happens
/D:/Dropbox/Coding/Intellij%20IDEA/TishenkoKPO/target/classes/static/master-key.txt
java.io.FileNotFoundException:
D:\Dropbox\Coding\Intellij%20IDEA\TishenkoKPO\target\classes\static\master-key.txt (System cannot find the specified path)
I've googled alot but have no clue of why this happens
Edit 1:
Part of the code rebuilt as community suggested (working with file as a resource)
InputStream is = getClass().getResourceAsStream("static/master-key.txt");
String masterKey = null;
Scanner scanner = new Scanner(is);
masterKey = scanner.nextLine();
System.out.println("the master key is " + masterKey); //successfuly outputs the first line if exists
Edit 2: resourcepath should begin with /
InputStream is = getClass().getResourceAsStream("/static/master-key.txt");
InputStream is = getClass().getResourceAsStream("static/master-key.txt");
This is searching for a resource relative to the package / directory of the class that is calling it. It is likely that resource can actually be found relative to the root of the application structure. To do that, add a leading /, like this.
InputStream is = getClass().getResourceAsStream("/static/master-key.txt");
Try this
getResource("resources\static\master-key.txt").getPath());
and if u targeting a path use '\' not '/'.
And u can try
YourClass.class.getResourceAsStream("resources\static\master-key.txt");
or
YourClass.class.getResourceAsStream("static\master-key.txt");

How to write any type of file (for example txt file) to a resources folder with the config.property file, but without using absolute path file in java

How to write or read any type of file (for example .txt file) to a resources folder with the config.property file, but without using absolute path file.
I tried to solve this like below:
ClassLoader classLoader = Setting.class.getClassLoader();
Setting setting = new Setting();
try (InputStream resourceAsStream = classLoader.getResourceAsStream("config.properties")) {
setting.load(resourceAsStream);
}
String readFileName = setting.getValue("pathSource.txt");
String writeFileName = setting.getValue("outPutPathSourceFile.txt");
String s = System.getProperty("line.separator");
File readFile = new File("./src/main/resources" + File.separator + "pathSource.txt");
File writeFile = new File("./src/main/resources" + File.separator + "outPutPathSourceFile.txt");
However, I don't want using ./src/main/resources prefix.
If your file is located under resources you able to access it like:
File file = new File(classLoader.getResource(fileName).getFile());
if you are using Spring you can use ResourceUtils.getFile():
File file = ResourceUtils.getFile("classpath:fileName")
UPDATE:
If I understand correctly, you want to read file which located under your src/main/resources without relative path usage /src/main/resources.
I created small demo:
public class ReadResourceFile {
public static void main(String[] args) throws IOException {
String fileName = "webAutomationConfig.xml";
ClassLoader classLoader = ReadResourceFile.class.getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
System.out.println("File exists: " + file.exists());
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);
}
}
Output:
File exists: true
<?xml version="1.0" encoding="utf-8"?>
<config>
<baseUrl>https://www.gmail.com</baseUrl>
</config>
Project structure:
Resources (files on the class path, possibly inside a jar)can be read, but are not intended to be written to. You can use them as template to create an inital copy on the file system. – Joop Eggen

Properties file not found - how to locate it as resource?

I have a properties file at location (from netbeans project explorer)
-MyTest
+Web Pages
+Source Packages
-Test Packages
-<default package>
+Env.properties <---- Here it is
+com.mycomp.gts.test
+com.mycomp.gts.logintest
.....
....
Now when I am trying to find this file using code
InputStream propertiesInputStream = getClass().getResourceAsStream("Env.properties");
ENV.load(propertiesInputStream);
Its throwing java.lang.NullPointerException
You cannot use the class as a reference to load the resource, because the resource path is not relative to the class. Use the class loader instead:
InputStream propertiesInputStream = getClass().getClassLoader()
.getResourceAsStream("Env.properties");
ENV.load(propertiesInputStream);
Or alternatively, you can use the context class loader of the current thread:
InputStream propertiesInputStream = Thread.currentThread()
.getContextClassLoader().getResourceAsStream("Env.properties");
ENV.load(propertiesInputStream);
String basePath = PropertiesUtil.class.getResource("/").getPath();
InputStream in = new FileInputStream(basePath + "Env.properties");
pros.load(in);
Good luck:)
Try to get absolute path with:
String absolute = getClass().getProtectionDomain().getCodeSource().getLocation().toExternalForm();
You can print out the string absolute and try to substring it to your path of your properties file.
The below code reads a property file stored within the resources folder of a Maven project.
InputStream inputStream = YourClass.class.getResourceAsStream("/filename.properties");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
Properties properties = new Properties();
properties.load(reader);
} catch (IOException ioException) {
ioException.printStackTrace();
}

Can I delete a JAR after I accesed its internal file through URL?

In Groovy, I am reading a file from inside a JAR, and after some processing, I wish to delete this JAR, but once accessed through the URL, it doesn't seem to let me.
Example:
File jarFile = new File('jarFile.jar')
URL url = jarFile.toURI().toURL()
URL intUrl = new URL("jar:$url!/internalFile.json")
println intUrl.text // reads text correctly
jarFile.delete() // returns false, cannot delete
The Javadoc of the getText() command says the connection is closed at the end of the call, and this JAR normally isn't on classpath. Is there any way to make this code work?
Try setting the sun.zip.disableMemoryMapping system property:
java -Dsun.zip.disableMemoryMapping=true ....
(or however you set system properties when invoking Gradle). ZipFile (which backs jar: URLs) uses memory mapping by default, and this may be causing Windows to think that the file in question is still open. If this is not an option then you could try using the commons-compress ZipFile implementation instead of the java.util.zip one:
#Grab(group='org.apache.commons', module='commons-compress', version='1.4.1')
import org.apache.commons.compress.archivers.zip.*
File jarFile = new File('jarFile.jar')
ZipFile f = new ZipFile(jarFile)
ZipArchiveEntry json = f.getEntry('internalFile.json')
if(json) {
f.getInputStream(json)?.withStream {
println it.getText('UTF-8')
}
}
f.close()
jarFile.delete()
You could try this:
import java.util.zip.ZipFile
File jarFile = new File( 'jarFile.jar' )
String text = new ZipFile( jarFile ).with { zf ->
String result = zf.entries().findResult { ze ->
if( ze.name == 'internalFile.json' ) {
zf.getInputStream( ze ).withReader {
it.text
}
}
}
zf.close()
result
}
println text
jarFile.delete()
To avoid (what I suspect is) the classloader locking the jar file

Categories

Resources