Java path in Linux - java

I have a bit problem, and i dont seem to understand what is causing it.
i have a folder in my project, and in that folder i have a class, and i have a resource file (in this case jasper report).
but the only way i can access file is with absolute path or some path that starts from root of my project.
String path = "src/main/java/Views/LagerMain/lager.jrxml";
^^this works, both my class LagerController and lager.jrxml are under LagerMain folder, but when i try to do this :
String path = "lager.jrxml";
i have an error that file is not found.
I tried googling this to have a better understanding but i found nothing.
Bottom line, why cant i access my file, from class when they are both on same place, why does not relative path work.

If the main class is in a different directory, then the program will try to accesslager.jrxml there instead of the directory of the regular class.
For regular-class directory:
String path = new String(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.getPath() + System.getProperty("line.separator") + "lager.jrxml");
If that doesn't work, try this:
// your directory
File f = new File("src");
File[] matchingFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("lager") && name.endsWith("jrxml");
}
});
If you have more than one file with the name lager.jrxml, then this method will return both of them and you will need to use a for to cycle through them. Otherwise, you can just use
String path = new String(matchingFiles[0].getAbsolutePath())
For main-class directory:
String path = new String(System.getProperty("user.dir")
+ System.getProperty("line.separator") + "lager.jrxml");

Related

Java: How to get path of a file when running JAR file

When I use relative path, I can run my Java program from Eclipse. But when I run it as a JAR file, the path doesn't work anymore. In my src/components/SettingsWindow.java I have:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./src/files/profile.ser"));
I get a FileNotFoundException.
My file directory looks like this:
file directory
What I've tried:
String filePath = this.getClass().getResource("/files/profile.ser").toString();
String filePath = this.getClass().getResource("/files/profile.ser").getPath();
String filePath = this.getClass().getResource("/files/profile.ser").getFile().toString();
And I'd just put filePath in new FileInputStream(filePath) but none of these work and I still get a FileNotFoundException. When I System.out.println(filePath) it says: files/profile.ser
I'm trying to get the path of src/files/profile.ser while I'm in src/components/SettingsWindow.java
You can get the URL to the class:
String path =
String.join("/", getClass().getName().split(Pattern.quote(".")))
+ ".class";
URL url = getClass().getResource("/" + path);
which will either yield "file:/path/to/package/class.class" or "jar:/path/to/jar.jar!/package/class.class". You either can work with the URL or use
JarFile jar =
((JarURLConnection) url.openConnection()).getJarFile();
and use jar.getName() to get the path to parse to get your installation directory.
To get the current JAR file path I use:
public static String getJarFilePath() throws FileNotFoundException {
String path = getClass().getResource(getClass().getSimpleName() + ".class").getFile();
if(path.startsWith("/")) {
throw new FileNotFoundException("This is not a jar file: \n"+path);
}
if(path.lastIndexOf("!")!=-1) path = path.substring(path.lastIndexOf("!/")+2, path.length());
path = ClassLoader.getSystemClassLoader().getResource(path).getFile();
return path.substring(0, path.lastIndexOf('!')).replaceAll("%20", " ");
}

File is not deleted when file path is generated dynamically

I am facing a problem but have not able to solve it yet. Let me share what I have done till now. I tried to delete a file using java.nio.file packages. And below is my code.
// directory will be dynamically generated.
String directory = fileDirectory+ "//" + fileName;
Path path = Paths.get(directory);
if (Files.exists(path)) {
Files.delete(path);
}
I generated the path correctly. But when Files.exists(path) calls it return false. That's why file is not deleted. But if I generated the directory string by hard-coded than it works perfectly.
// hard-coded directory works perfectly.
String directory = "C://opt//tomcat//webapps//resources//images//sprite.jpg";
I also tried the another method Files.deleteIfExists(path);. Which check the both the file existence and delete the file.
The other packages org.apache.commons.io.FileUtils and java.io.File have tried. But can't resolve the issue.
Note: My application is in spring-boot. And I read the directory from the application.properties file for both save images and delete images.
EDIT:
file uploading I mean save into the directory is perfectly worked. But file deletion does not work.
application.properties
image.root.dir=images
image.root.save.dir=C:/opt/tomcat/webapps/resources/
in implementation file
#Value("${image.root.dir}")
private String UPLOADED_FOLDER;
#Value("${image.root.save.dir}")
private String saveDir;
String directory = saveDir + UPLOADED_FOLDER + "/" + fileName;
save file into directory
String directory = saveDir + UPLOADED_FOLDER + "/";
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(directory);
if (!Files.exists(path)) {
Files.createDirectories(path);
}
path = Paths.get(directory, file.getOriginalFilename());
Files.write(path, bytes);
} catch (IOException e) {
logger.error("save image into directory : " + e);
}
String directory = fileDirectory+ "//" + fileName;
This is not the correct separator used between a directory and a file name, though it seems to work as well.
This means the problem is not the separator, but a mismatch between the code that you use to generate the path and this code. You're generating the directory into somewhere else than where this is pointing.

Is it possible to assign a String variable the absolute path of a File?

I am wondering if it is possible to assign a String Variable the path of the file? If Yes, then is it possible to update the File Dynamically?
I am trying to create Files dynamically (which I am able to do so), but I want to link these dynamically created files to a String variable.
Please help. Thanks in advance.
File dir = new File("Data");
if(!dir.exists()){
dir.mkdir();
}
String filename = "file1";
File tagfile = new File(dir, filename+".txt");
if(!tagfile.exists()){
tagfile.createNewFile();
}
System.out.println("Path : " +tagfile.getAbsolutePath());
String s = new File("xyz.txt").getAbsolutePath();
or
String s = new File("xyz.txt").getCanonicalPath();
Both of the above assign (in my case) c:\dev\xyz.txt to the string s.
To get the full system path windows or linux
public static void main(String []args){
String path = "../p.txt";//works on windows or linux, assumes you are not in root folder
java.io.File pa1 = new java.io.File (path);
String s = null;
try {
s = pa1.getCanonicalFile().toString();
System.out.println("path " + s);
} catch (Exception e) {
System.out.println("bad path " + path);
e.printStackTrace();
}
Prints out full path like c:\projects\file\p.txt
Here is the code to do that:
File file = new File("C:\\testfolder\\test.cfg");
String absolutePath = file.getAbsolutePath();
This is what javadoc says about the getAbsolutePath API:
getAbsolutePath
public String getAbsolutePath() Returns the absolute pathname string
of this abstract pathname. If this abstract pathname is already
absolute, then the pathname string is simply returned as if by the
getPath() method. If this abstract pathname is the empty abstract
pathname then the pathname string of the current user directory, which
is named by the system property user.dir, is returned. Otherwise this
pathname is resolved in a system-dependent way. On UNIX systems, a
relative pathname is made absolute by resolving it against the current
user directory. On Microsoft Windows systems, a relative pathname is
made absolute by resolving it against the current directory of the
drive named by the pathname, if any; if not, it is resolved against
the current user directory.
Returns: The absolute pathname string denoting the same file or
directory as this abstract pathname

Unable to load the file from filesystem using ResourceBundle

public static void loadFilters() throws MalformedURLException {
File filtersFile = new File(CONFIG_DIR + "/" + FILTERS_FILE);
URL[] urls = {filtersFile.toURI().toURL()};
ClassLoader loader = new URLClassLoader(urls);
ResourceBundle bundle = ResourceBundle.getBundle(FILTERS_BASE, Locale.getDefault(), loader);
if (StringUtils.isNotBlank(getStringValue(bundle, ALLOW_TYPE_PATTERN_KEY))) {
ALLOWED_TYPES = Pattern.compile(getStringValue(bundle, ALLOW_TYPE_PATTERN_KEY));
}
if (StringUtils.isNotBlank(getStringValue(bundle, DENY_TYPE_PATTERN_KEY))) {
DENIED_TYPES = Pattern.compile(getStringValue(bundle, DENY_TYPE_PATTERN_KEY));
}
ALLOWED_MIME_TYPES = getListValue(bundle, ALLOW_MIME_PATTERN_KEY);
DENIED_MIME_TYPES = getListValue(bundle, DENY_MIME_PATTERN_KEY);
}
I am trying to load properties file using resource bundle kept outside the code in a separate directory. But when I try to do this way(above code) I am getting error as
ERROR [main] Can't find bundle for base name filters, locale en_US
And If I am keeping this file filters.properties in src/main/resources folder then this code is working fine... but when I keep it outside it doesn't works.. Don't know why..
And CONFIG_DIR contains \my\dir\conf and FILTERS_FILE contains filters.properties file.
FILTERS_FILE has value filters.properties and FILTERS_BASE has value filters and urls got the value as [file:/C:/my/dir/conf/filters.properties]
And filters.properties file is in /my/dir/conf/filters.properties
Try having the file point to the directory rather than the actual properties file. So just change the first statement of that method to
File filtersFile = new File(CONFIG_DIR + "/");
If FILTERS_BASE contains filters, that should be enough. You don't need the full filters.properties name since the .properties prefix is appended by the getBundle method.

How to reference files in a Java Pacakage

I have MyClassin package X, Also in package X there are packages Y and Z like this:
X - MyClass
X - Y - Some Files
X - Z - Some Files
How do I get a list of all the files in packages Y and Z from MyClass?
Java packages mirror directory structure. You can use the File class. In particular, see the listFiles() method.
EDIT
You can dynamically find your executing location. Here is code from a project I've recently worked on; I wanted to be able to find the directory I'm running the JAR from (if I'm running the JAR), or else the directory of the JAR if I'm running from the class files. In my case, my JAR is in <project root>/bin and my classes are in <project root>/classes.
final URL location;
final String classLocation = JavaPlanner.class.getName().replace('.', '/') + ".class";
final ClassLoader loader = JavaPlanner.class.getClassLoader();
if(loader == null)
{
try { throw new ClassNotFoundException("class loaded with bootstrap loader"); }
catch (ClassNotFoundException cnfe) { throw new InitializationException(cnfe); }
}
else
{
location = loader.getResource(classLocation);
}
if(location.toString().startsWith("file:/")) // Line 14
{
// Running from .class file
String path;
try { path = URLDecoder.decode(location.toString().substring(6), "UTF-8"); }
catch(UnsupportedEncodingException uee) { throw new InitializationException(uee); }
// Move up package folders to root, add /bin/
File package_ = new File(path).getParentFile();
binPath = package_.getParentFile().getParentFile().getParentFile().getParentFile() + File.separator + "bin" + File.separator;
}
else // Line 25
{
// Running from .jar file
String jarURL = JavaPlanner.class.getResource("/" + JavaPlanner.class.getName().replaceAll("\\.", "/") + ".class").toString();
jarURL = jarURL.substring(4).replaceFirst("/[^/]+\\.jar!.*$", "/");
try
{
File dir = new File(new URL(jarURL).toURI());
jarURL = dir.getAbsolutePath();
}
catch(MalformedURLException mue) { throw new InitializationException(mue); }
catch(URISyntaxException use) { throw new InitializationException(use); }
binPath = jarURL;
}
At line 14, I've found that I'm running the application from a class file. String path initially is set to the file path of JavaPlanner (the class containing my main method). I know the package structure JavaPlanner is in, so I use getParentFile an appropriate number of times to find the project root, and then append bin/.
At line 25, I've found that I'm running the application from a JAR. The block simply gets the path to the folder containing that executable JAR.
Obviously, this code is not 100% adapted to your purpose (most specifically, I'm calling getParentFile a specific number of times for my package structure), but I think it should help.
The entire purpose of the above code was to be able to find the correct resource files for my application. In the production version, only the JAR would be available to the user, but I didn't want to have to rebuild the JAR every time I needed to test some code, and I didn't want to duplicate my resource files, and I didn't want to pollute my bin/ folder with the class files (because everything in bin/ was meant to be sent to the user).
It depends on the source of the class. If they are from a JAR file, then you can use the JarFile class to get a list of entries.
If you're only looking for classes in the package, consider
Package.getPackage(String name)
Package.getPackages()
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Package.html#getPackage%28java.lang.String%29
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Package.html#getPackages%28%29

Categories

Resources