This Java code lists files in a directory on a Windows shared drive. Will it work correctly on a Unix system?
File directory = new File("\\\\server/Shared/stuff/mystuff");
for (File file: directory.listFiles()) {
System.out.println(file);
}
Short answer: No.
Long answer: Do you have samba installed? Even then you need to mount the the share. So it probably won't work.
EDIT
Java delegates the call to the underlying OS eventually. Since Unix doesn't know what the \\SERVERNAME path means, Java doesn't know what it means either. What you have to do, to get this to work is mount the drive explicitly using Samba. Your other option, if you are running Ubuntu, is look under .gvfs in your home directory. Ubuntu creates a mount there for your Samba shares, which you should be able to access using Java. If you don't want to rely on external tools, try JCIFS for a pure-Java solution.
No...
Just let the user select the right path and use an OS dependent file-selection dialog.
On my system (Debian Sid with Gnome 2.30 Desktop) I have to select "smb:///server/Shared/..." to achieve the same behaviour. I think, that GVFS (Gnome Virtual File System) using smbfs drivers handles the real connection in the background...
No, as that is a UNC Path, which is a windowsism.
Are you trying to access a windows share from unix? Then have a look at jcifs.
The counter question I get when seeing this is: "Why would you want to hard-code a path in your application?"
Even if it was just for the example and you intend to load the path from a property file or anything, I still think you are on the wrong track here.
First of all you will want to avoid absolute paths like the plague. Relative paths are sort of ok. You can use slash ('/') characters in paths hardcoded, it will work on both Windows and Linux/Mac. Basically all platforms.
Second of all, why use paths at all? This is the internet age. Use URL's! file: URL's will accomplish the same thing as file paths, but using URL's make your app accept resources from other sources such as web sites and FTP as well.
Third of all, avoid the File class. If you invent a good way to do that, you are out of the woodworks completely. Use URL's together with getResource and getResourceAsStream and your app will work platform independent and across network boundaries over the internet.
Related
I am working on a java application, it’s has a trial version.
I need to save all informations to activate the application in an xml file ( such as expired day and application ID ), i need to save this file in an absolute path that will be the same for all pc.
Can u help me please?
Don't. It's very bad practice to use absolute paths for anything.
Why not save the XML file either to a folder specific to the user (if your licenses are bound to people), or to a folder relative to your application (if your licenses are bound to a machine, as your question seems to indicate)?
I agree that using absolute paths may not be the way to go but to solve your problem you could get the name of the user like so
String username = System.getProperty("user.name");
From there you can use the windows file structure to get to the documents folder
String documentsFolder = "C:/Users/"+username+"/Documents";
With that directory path you can read and write to that folder. This folder structure would only apply to windows and would need to be changed for Mac or Linux machines, but the username can be obtained the same way.
Just a suggestion. If you are supporting windows machines only maybe you can create a registry with the start and end date of the application and use that as a reference point which will be consistent even if the application is uninstalled or re-installed. Also maybe creating a System variable with the date could be another way to go. Just a few thoughts.
Hope this helps
I am sure this is a relatively simple question, and I actually think it may be more of a problem with Windows than with Java.
I have a method for copying a file to a new directory, which takes two File objects, a File created with the path of the original, and a File created with the desired path of the copy. I am sure that the method works because I have used it to successfully copy a file onto my Desktop.
However, using my actual desired path creates an error:
java.io.FileNotFoundException: PATH (The system cannot find the path
specified)
Where the PATH is the path that I am attempting to use.
Here is my guess:
I am making this program for use on another machine. As such, the path that I am trying to use is:
C:\Users\XXXXXX\rest_of_path\filename.file
where XXXXXX is the primary user on the machine which I am writing the program for.
This directory exists on my system, but XXXXXX is not a user on my system. So I am guessing that Windows is causing a problem because of that.
I'm now changing my code to use a solution which depends on the machine, and is not hardcoded (System.getProperty).
However, I'd really like to know why this problem is occurring, from an academic standpoint, as a Windows and Java user.
Thanks in advance.
EDIT: accidentally used forward slashes when I meant double backslashes. To ensure that it was not a spelling error, I simply copied the directory using windows, and pasted it into my program (then doubled up on the backslashes).
EDIT: several users have suggested something which is far more clean than what I am trying to do in the first place. I'm leaving this question open because I'm curious why it is not working.
EDIT: I used the solution above and I'm completely happy with it. I still don't know why Windows will not allow me to access the original path, but I guess I really don't care at this point. Thanks, everybody!
In java, and generally most programming languages, you don't always have to provide the exact directory of your file. Although it would be nice to see the code you're using to get the file, I'll provide how it can be done.
I'm assuming you aren't using new File("file.txt") because that retrieves files from the folder your program is in, and doesn't require an entire address like C:\...\...\.... You certainly don't want to use an entire address because different operating systems use different paths, obviously.
The best you can do is put your files and requested folders somewhere relative to your program is (whether it's class files or a .jar file).
But with Windows you can be sure that with System.getProperty("...") you can retrieve directory URLs as relative paths for your files/folders.
Documentation on System.getProperty here: http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
I may not have helped or answered your question at all. But hopefully you'll find a solution.
In Linux, I'll usually put user configuration files in $HOME/.myapp and in Windows I'll use APPDATA. So far so good.
What about non-user specific configuration? In linux, I'd put it into /etc. Is there an equivalent in Windows? Please note I would like to have the service running before any user logs in. Also, in case it plays a role, I'm developing in Java.
Alternatively: I approaching this the wrong way?
You could use ALLUSERPROFILES as a base directory. This environment variable resolves to the C:\PROGRAMDATA folder in Windows7. Of course you need to add a specific folder for your applications
In summary, you should use the known folder: ProgramData.
To avoid hard coding of paths (and hence why I'm not providing them here) you should always retrieve the value via one of the following methods:
The %PROGRAMDATA% environment variable (you can also use %ALLUSERSPROFILE% but I consider %PROGRAMDATA% more meaningful)
For unmanaged code use SHGetKnownFolderPath, passing the FOLDERID_ProgramData.
For managed code use System.Environment.GetFolderPath, passing CommonApplicationData.
This folder is not writeable by non-admins, so depending on your requirements you'll want to create a directory for your program and set the ACLs you need at install time.
Some good information on this topic is provided in the blog post: "Where Should I Write Program Data Instead of Program Files".
For those interested in using other Known Folders, MSDN provides extensive documentation.
In Windows most "program files" for an app go in C:\Program Files\MyApp. The environment variable would be %ProgramFiles%\MyApp.
I write cross-platform java app and I need some place where I can store some amount of files. These files will be used by another java application that may run under another user. This mean that I cannot use:
System.getProperty("user.home");
since I may have no permissions to read/write these files. What I need is some way to get non-user-specific folder where every app can create/read/delete files (something like "C:\ProgramData" for windows).
Is there a cross-platform way to get such folder(at least for Windows and Linux), or if there is no any - what is the best way to get such folders for Windows(should work on XP-7), Linux and Android.
Any pieces of puzzle are welcomed.
I'm not aware of such such a cross-platform folder which is additionally readable by all users. But you can:
Define a specific folder for each OS, commons-lang may help you determining the platform (see SystemUtils)
Check if the folder read/writeable for the current user during application start-up.
Using a central configuration (where the data exchange folder is defined for this installation) may also be an option, but this depends on the packaging of your project.
I have a program, written in Java, which originally used its directory in Program Files to write files accessible to all users of this program. This required our users to run as administrator all the time. In an effort to alleviate that, we decided to move files which needed to be written during regular usage to the ProgramData folder using the %ALLUSERSPROFILE% environment variable. Using a subfolder in this directory for our application works great if it is designated as writable during the installation process, which works fine using NSIS.
The problem comes with upgrading existing users. The Java File API provides setWritable but this does not appear to work after testing on development machines. It looks as though the new file API with Java 7 would solve this problem, but with no release date on the horizon I would rather not wait.
It seems the simplest solution would be to use JNA to call the appropriate Windows API call to set this directory writable. Since upgrading the software necessitates admin rights, similar to installing, it should let this change go through fine. However, I'm unsure where to start, having never used JNA before or the Windows API. Suggestions as to which Windows library to load and what functions to call would be appreciated, especially if someone has encountered a similar problem before.
Well, I'm glad you gave some background...You could use JNA, but the easier way would be to execute a call to the command-line utility cacls. It's included by default in Windows XP installations, I believe, so it should do the trick for you. Try Runtime.getRuntime().exec("C:\\Windows\\System32\\cacls.exe"+options)
Check out the documentation here -> http://technet.microsoft.com/en-us/library/bb490872.aspx
I use the follow line:
Runtime.getRuntime().exec( "C:\\Windows\\System32\\icacls.exe \"%ProgramData%\my application" /grant *S-1-5-32-545:(OI)(CI)(W,M)" );
S-1-5-32-545 is the SID for BUILTIN\Users because the name work only on English systems. https://support.microsoft.com/de-de/kb/163846
This give the BUILTIN\Users write access to all files in the given directory independent which user has create it.