Windows temp directory details (Java) - java

I'm writing a program that needs a generic temp folder. I'm trying to find details about the Windows Temp folders. There are two paths that I know about -
In each user directory under AppData\Local\Temp\
This may change depending Windows version?
In the system folder under Temp\ (C:\Windows\Temp)
I'm wondering exactly what Windows does to each of these. If Windows deletes files from either location, when does it do so? How can/should I use these directories for my programming?
EDIT: I have a bigger problem actually - Because of a certain engine I'm running indirectly with my program, which uses files I'm creating in a temp directory, I need a temp directory that doesn't use whitespace characters in the path. Java's System.getProperty("java.io.tmpdir") on Windows gives me the temp that's in the user directory, which on XP is under "Documents and Settings..."
Not good. Any suggestions? This is why I'm wondering about the C:\Windows\Temp\ directory...

This will give you the path to the windows temp directory in Java.
File.createTempFile("temp-file", "tmp").getParent()

Not quite. There is a user and system folder, the default location of which varies according the windows version, system folder name, and indeed in older versions of windows was the same for both the user and system case. However, these defaults can be over-ridden (they are on the system I'm using now, where they aren't on the same drive as the system folder).
The locations are stored in system variables. Some frameworks (.NET, VB6 and no doubt others) give you convient ways to find the paths rather than having to look up the system variable (e.g. System.IO.Path.GetTempPath in .NET).
Windows does not clean up the temporary folder for you (which is why it's worth blasting out old files it every few months on your own machine), it's up to you to play nice. Create a file or files unlikely to step on the names any other software is using (they should take care to do the same, and so any name should do, but it's always good to assume the worse of other code on the system), and delete files when you're done (or on application exit at least).
In .NET System.IO.Path.GetTempFileName() will create a new file in the temp area and return the name of it to you, that is reasonably guaranteed not to conflict with others' so use that or similar methods if you can.

It sounds like you have two programs that need to share temp files and one definitely doesn't want spaces in the path name. Probably the easiest thing to do is:
set the TMP and TEMP variable to a common directory
launch each application (from this modified environment) - which should pick up the temp variable
So at the command prompt you could do this:
set TMP=c:\mytemp
set TEMP=c:\mytemp
java -cp x;y;z my.application.Entry
run other application (hopefully it also reads the environment for temp/tmp)
Hope that helps.

To answer part of your question - if you're using .NET, you can use the Path.GetTempPath() method of the System.IO namespace to get the location of the temporary directory.
// Get the path of the temporary directory
string tempDir = Path.GetTempPath();
// "Creates a uniquely named, zero-byte temporary file on disk and returns the full path of that file."
string tempFile = Path.GetTempFileName();

The %TEMP% environment variable that's defined on my PC (XP SP3) uses the DOS-style abcdef~1 directory names - hence, if you can pull that variable, you should end up with a path without spaces.
e.g. Start>Run>%TEMP% takes me to C:\DOCUME~1\<user>\LOCALS~1\Temp
However, if a 'super-user' fiddles around with that variable and points it somewhere else, it's possible that things will fall over. You could look at something like this to retrieve the 8-char-and-no-spaces path.

use this code
try { String s=File.createTempFile("temp-file", "tmp").getParent();
System.out.println(s);
} catch (IOException ex) {
Logger. getLogger(Result.class.getName()).log(Level.SEVERE, null, ex);
}

you can try this way
System.out.println(File.createTempFile("temp-file", "tmp").getParent());
String property = "java.io.tmpdir";
String tempDir = System.getProperty(property);
System.out.println("OS current temporary directory is " + tempDir);

Related

How can I get the path of the compiled jar file via code?

I want to use image files for my java program, and for that I need File objects. But I have the problem that when I build my project, the project name has a .jar at the end of the name, making a File object like new File("..\\Project\\src\\ImageDirectory\\Image.png") useless, since the directory doesn't exist.
I've found out I could tecnically iterate through all the directorys on the computer but I don't want to do that because that could take some time with high amounts of directories and harddrives.
So, is there a reliable and easy way to get the directory the jar file is currently in?
My IDE is InellijIDEA
You can use Path to do this:
Path path = Paths.get(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
Path have several methods to get more information.
For example, i have this JAR in Desktop and i am printing this:
System.out.println(path);
System.out.println(path.getRoot());
System.out.println(path.getParent());
The results are:
java -jar C:\Users\gmunozme\Desktop\Test.jar
C:\Users\gmunozme\Desktop\Test.jar
C:\
C:\Users\gmunozme\Desktop
Check that out,
Hope you can use it.

Saving a file in Windows

I have a folder called WalnutiQ. Inside this folder is is a file at WalnutiQ/train/model/MARK_II/Save.java
Save.java
JsonFileInputOutput.saveObjectToTextFile(myObjectJson,
"Digits.txt");
which works! However, the file Digits.txt is unfortunately saved in WalnutiQ/Digits.txt
How do I save the file Digits.txt at WalnutiQ/train/model/MARK_II/Digits.txt???
I am programming in java in eclipse in windows. I have tried
JsonFileInputOutput.saveObjectToTextFile(myObjectJson,
"/train/model/MARK_II/Digits.txt");
JsonFileInputOutput.saveObjectToTextFile(myObjectJson,
"\\train\\model\\MARK_II\\Digits.txt");
but neither work.
judging from the result you are getting your current directory is pointed at WalnutIQ. You might try using .\train\model\MARK_II\Digits.txt. Windows treats the . (period) as a token for "current directory". Your other attempt would have tried to find the train directory in the root of C because the \ (backslash) is a token for the root (c:). It likely fails because that folder does not exist - unless it created it... might go look :) I don't use Json in eclipse which is why I'm not answer your question with code.
Have you considered using the full absolute file path to the text file, rather than the relative one you are currently using? This may not be practical, depending on how you plan on using your program, but it might be worth a shot.
Depending on how the library saves files (I imagine it's using File behind the scenes), you should be able to supply an absolute path to the location you want it to save to.
JsonFileInputOutput.saveObjectToTextFile(myObjectJson,
"/path/to/WalnutiQ/train/model/MARK_II/Digits.txt");

Getting the current user's path rather than application path in java

I am trying to get the current users path in a giant command line application that has multiple dependencies. Every time a "." is used, it gives me the application path (where the jar exists), rather than the current user path(where the call is being made).
So, when this is ran:
File file = new File(".");
System.out.println(file.getCanonicalPath());
Gives me the path that the application exists in.
But when I create a separate small application, and use the same code. Call the jar from a different directory, it gives the current user path.
I am using JSAP command line parser for the command line arguments, its acting the same way. How can this be solved? I want my big application to get the current user path, not application path.
What would cause them to behave differently?
I think you'll find that the batch file (/shell script) which launches your "big application" is changing directory to the main jar file's directory before kicking off Java, which is why your simple test application returns the user's working directory for new File(".") while the big app returns the jar file's directory.
Try storing the user's CWD early in the batch file and then passing it to Java:
set savedcwd=%cd%
... later on ...
java "-Dsavedcwd=%savedcwd%"
then in your application
String savedcwd = System.getProperty("savedcwd");
http://www.mindspring.com/~mgrand/java-system-properties.htm
you want "user.home" property, like
System.getProperty("user.home");
String currentDir = new File(".").getAbsolutePath();
OR
System.getProperty("user.dir")
1) As stated above, if you want to get "current directory", one way is to use File(".").getAbsolutePath()
2) If you want to get the user's $PATH variable (or any environment variable), use System.getenv():
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html

Java on MacOSX: how to access files in the bundle

I have a Java app which I am packaging to a Mac Application Bundle (That folder structure that contains all of the app but looks like a single executable file to the user).
My Problem:
I am reading and writing some config files in the local folder ("."). However, on Mac this seems to be the folder in which the application bundle is located (so usually the "Applications" folder and I obviously don't want that.
My question:
How can I store a file inside that bundle? How can I programmatically retrieve the bundle name to compute the fully qualified folder?
I know I could try to go the ClassLoader way, but I'd like to avoid that (for security reasons).
Or is there simply a better way how to store application cache and config data locally?
The Mac OS X Finder treats any directory whose name ends in .app as an application; right-click to Show Package Contents. It remains an otherwise normal directory for I/O purposes. This project is an example. See this answer regarding paths relative to the application bundle.
Addendum: Is there a better way how to store application cache and config data locally?
The example cited uses java.util.prefs.Preferences, but javax.jnlp.PersistenceService is an alternative.
Ok, the basic answer / solution is: don't do it.
The reason I originally wanted to do it was to cache larger amounts of data on the local HD. Java preferences are a good choice for config data (i.e. small data amounts) but fail to handle data in the megabyte size range.
My solution:
On MacOSX (System.getProperty("os.name").contains("Mac OS X")) I simply create a folder in the user's home folder (System.getProperty("user.home")). I prefix that folder with a . to ensure it is hidden from the user. This also ensures that I have write access to the folder (which could be a problem in the .app folder depending on where the user copies it)
On Windows (System.getProperty("os.name").contains("Windows")) I create that folder in the System.getenv("APPDATA") directory (note that this env variable only exists on Windows systems.
Now I have full access to the filesystem (even without admin rights) and can store as much data as I like.

Java: Where to write config without requiring administrative rights

I actually can't believe I'm saying this but since porting my programs to OSX and getting used to permissions, I've realized that what I planned to do on Windows will not work how I want it to. Currently, on windows, my program stores it's setting's in the registry (HKLM) and some user editable resources in a folder next to the program file. For various reasons, I have now decided that the configuration/settings will be stored in a file and the user will be able to in which folder the other resources are kept.
So the question I have now is where to store the configuration file. Obviously it will be updated, but I don't want to program to have to require administrator permissions to run. I would like to offer an option so that all users can use the program (like most programs do), which will of course require Admin, so this leads be onto the second query: where should I store the configuration file (and the folder in which other resources are kept) and how can I detect whether the program has been installed for all users or just one!
Thanks in advance
PS If you didn't guess, the program is written in Java so I would like to know how to programatically get the location you suggest as well please.
Its normal practice in *nix compatible programs to store information in folders starting with name . in the home directory of the users like,
.bash_history
.bashrc
You could use the same on OSX in my opinion and create a directory say,
.myapp
You can store any number of files with any format under that directory.
To get the location of the folder, you can do
String homeDir = System.getProperty("user.home");
File myAppDir = new File(homeDir, ".myapp");
That is roughly the code that can get you your custom config directory for your app.
Please not that dot files / folders are somewhat similar to hidden folders in windows. Your File Manager will not generally show these files / folders by default.
To identify if the program is installed for all the users or not, you could create the configuration at some administrator (root) controlled location like /etc (not sure about Mac) The user configuration can always override the default config. There could be a better way to handle this though.
On both windows and unix, User(usually) has a (home)folder to which it has full permissions. You may create a directory in the home folder and have your user configuration files reside there.

Categories