System.getProperty("user.dir") alternative - java

I would like to write JSon files in my Java Application, it works perfectly in my IDE but as soon as I move the directory, the system fails to write the file. I eventually found the problem : The line System.getProperty("user.dir") returns a bad path.
The files are located in C:\wamp\www\myProject during development. Here is my code at the moment :
String url = System.getProperty("user.dir") + "\\src\\json\\Crc.json";
//Returns "C:\wamp\www\myProject\src\json\Crc.json"
After moving my project to C:\Users\myUser\Desktop :
String url = System.getProperty("user.dir") + "\\src\\json\\Crc.json";
//Returns "C:\Users\myUser\src\json\Crc.json"
I would like to have a way to find where my project directory is on the computer at anytime. Do you guys have a solution ?

The C:\wamp\www\myProject folder is just a random place on your hard disk.
Java supports 3 generic places to look for resources:
the current working directory. this is where your command prompt is and what System.getProperty("user.dir") returns, but you cannot rely on that beeing somehow related to any cretain place in the file system, especially not related to the project structure on your own system.
You should only use that if your program has a command line interface and looks for some default file name to work with.
the user home This is what you get when calling System.getProperty("user.home"). On Unix this resoves to $HOME and on Windows to %USERPROFILE%.
This is the best place for files changed at runtime or holding user specific content.
the own code location. Resources in the same package as your class are accessed with getClass().getResource("filenameWithoutPath") But usually you place resources in a special folder in the application root and access it like this: getClass().getResource("/relative/path/from/src/root/filenameWithoutPath").
In your IDE this special folder should be Project/src/main/resources (according to the maven Standard Directory Layout
This is appropriate for some global configurations that you change when creating the delivery package.

Related

Scanner cannot find (correct) file path

I'm programming in Java with IntelliJ and have been trying to use the Scanner class to read the file. Even with the correct path, I still get a "No such file or directory" error. Does anyone have any suggestions?
My working directory is /Users/kevinliu/Desktop/test
Here is a picture of how the project is set-up.
Are you trying to create a swing/console application using maven?
If yes, maven is not able to find the source. You have to add it on the pom file. See here on how to add it on pom file.
if no, do you have rights to access the address of the image file? Some times, folder are protected by the OS.
You can also use YourClassName.class.getResource("input/input1.txt") to locate file/s under the directory that your class was in.
Even with the correct path, I still get a "No such file or directory" error.
The path is NOT correct. That path says look for a directory called "src" in the root directory of your computer. That is almost certainly not where the input file lives.
If you are going to use an absolute pathname for a file within the working directory that you stated, it should look like this:
/Users/kevinliu/Desktop/test/src/input/input1.txt
(You can check what it will actually be using a file browser ... outside of Intellij.)
If you want to use a relative pathname, try this
src/input/input1.txt
Notes:
There is no leading "/" on a relative pathname. A leading "/" means it is an absolute pathname. Absolute pathnames start at the root directory.
A relative path is resolved relative to the >>current<< working directory. That will depend on where and how you run the application ...
For a production application, you would not want to refer to a file in the source tree. The end user typically won't have the source tree.
Consider making the path a command line argument or configuration setting for your application.
Consider making the file a "resource" that is part of the application's JAR file. (You would open it a different way ...)
If you ever get a "No such file or directory" message, that means that the path is not correct in some sense. You might be in the wrong place, you might not have permission on a parent directory, the file may have been removed or renamed, there may be a you, or something else. Either way, that error comes from the operating system and the OS doesn't make mistakes about these things. The mistake will be yours (or the user's).

How to avoid hard code full path in Paths#get method

I want to save a copy of Primefaces UploadedFile to my project directory. I have been searching the internet for the solution, what I have found is using Paths#get method. The example given in this answer is Paths.get("/path/to/uploads");, the problem is, where is the exact path of /path/to/uploads? I can't find it. I mean where should I create the path /path/to/uploads? Under my project directory? but which folder? I solve this issue temporary by hard coding the full path like Paths.get("C:/uploads/");
FacesContext.getCurrentInstance().getExternalContext().getRealPath("/") will return you the current installation directory of your project.
And as #Kukeltje suggested, never ever save an uploaded file to your project directory, ... save it outside the webapps or even outside your container.
Therefore create a directory outsite your container (where you want to place your uploaded copies) and append ../ to the above path for each back step.
Say, if your application is deployed at D:/Tools/Tomcat7/webapps/your-application-name (e.g. on Windows using Tomcat) and you want to save copies to D:/Tools/uploads then following will give you required file path:
String uploadsFilePath = FacesContext.getCurrentInstance().getExternalContext()
.getRealPath("../../../uploads");
Use it with the Paths.get(uploadsFilePath) and develop your download logic (I am not sure which library you are using for the Paths class).
How about getClassLoader().getResource(Path/to/file)
So like
MyClass.class.getResource(bla/bla)
Which are now nested in src/resources
Like this You are system independent
#profit
You have several options:
For very quick development, you can use a hardcoded path, but be sure that it exists in your SUT (system under test).
You can define it as a static final string in your module, but this means that each time you want to change that path, you will need to recompile...
You can read that value from a property/config file.
There are more options (like using the registry if you are on Windows, or using an environment variable).

Sharing a Java Object Stream

I've got a project to do with 2 other classmates.
We used Dropbox to share the project so we can write from our houses (Isn't a very good choice, but it worked and was easier than using GitHub)
My question is now about sharing the object stream.
I want to put the file of the stream in same dropbox shared directory of the code.
BUT, when i initialize the file
File f = new File(PATH);
i must use the path of my computer (C:\User**Alessandro**\Dropbox)
As you can see it is linked to Alessandro, and so to my computer.
This clearly won't work on another PC.
How can tell the compiler to just look in the same directory of the source code/.class files?
You can use Class#getResource(java.lang.String) to obtain a URL corresponding to the location of the file relative to the classpath of the Java program:
URL url = getClass().getResource("/path/to/the/file");
File file = new File(url.getPath());
Note here that / is the root of your classpath, which is the top of the directory containing your class files. So your resource should be placed inside the classpath somewhere in order for it to work on your friend's computer.
Don't use absolute paths. Use relative paths like ./myfile.txt. Start the program with the project directory as the current dir. (This is the default in Eclipse.) But then you have to ensure that this both works for development and for production use.
As an alternative you can create a properties file and define the path there. Your code then only refers to a property name and each developer can adjust the configuration file. See Properties documentation.

distributing my java app, HOW do I manage directories

My java applications is almost complete and now I am giving it a finishing touch. Although certain code requires to read data from specific directories on the computer. On my machine I did it in the following way:
FileOutputStream fos=new FileOutputStream(C:/User/AnirudhVarma/Document/Appname/foldername/file,true);
But on the users machine how do I ensure that it creates it in the following directory?
C:/enduser/appname/folder/file
Hard coding folder structure in code is very bad idea.
One way to handle this is:
You need to have a properties file something like that where user need to enter path to required folder. Mention this as requirement in install docs.
In your code you need to make sure folder has required content before proceeding. If not valid folder, just show error message with proper information to setup the directory path.
System.getProperty("user.dir") will return C:/User/AnirudhVarma on you machine. From there, I'd suggest you need to consider the platform. Under windows, you should store this kind of information into the AppData folder.
So you would end up with something like System.getProperty("user.dir") + File.seperator + "AppData/Appname/foldername/file"
Under MacOS, I believe the convention is to use .AppName instead, something like System.getProperty("user.dir") + File.seperator + ".Appname/foldername/file"

Read File on Networkshare

I am running my Application from a network-share. For example: "\server\startProgramm.bat"
The Code in my startProgramm.bat:
java -jar %~dp0\app.jar
I need to open some config files. It is working local if i try to open them with:
new File("").getAbsolutePath() + "\\" + filename
but not on my Network share.
The config-files are in a subdir of the dir where my jar and bat files are.
new File("\\\\servername\\sharedDirectoryOnServer\\fileOnServer");
"Ok, this worked, but is there something like CurrentWorkDir?"
The current working directory is (by default) the one your program runs in. You can not change it within java (see here:
Changing the current working directory in Java?
),
the best practice is to just concatenate the server-path and file-name; but i think (not sure) it is also possible to start your program from the server (java \\server\\path\\myprog where there's a myprog.class in that directory) and make the working directory default to that path.

Categories

Resources