Getting file path for local Android project files - java

I want to programmatically access a specific file which will be included in my project folder. Is there a way to do this? If so, where in my project folder do I put the file, and what is some simple code to get its file path?
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
java.io.File spreadsheet = new java.io.File("Untitled spreadsheet.xlsx");
String filePath = spreadsheet.getAbsolutePath();
System.out.println("file path is"+filePath);
URL fileURL = getClass().getClassLoader().getResource("Untitled spreadsheet.xlsx");
String filePath2 = fileURL.getPath();
System.out.println("file path2 is"+filePath2);
java.io.File fileContent = new java.io.File(filePath);
FileContent mediaContent = new FileContent("application/vnd.ms-excel", fileContent);
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType("application/vnd.ms-excel");
File file = service.files().insert(body, mediaContent).setConvert(true).execute();
if (file != null) {
showToast("File uploaded: " + file.getTitle());
}
else
;
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}

Put the file in root folder of your project. Then get the File URL, Path and other details as:
File file = new File("test.txt");
String filePath = file.getAbsolutePath();
EDIT: Alternate way (if the file is in your classpath e.g. put the file in "src" folder, and make sure its moved in "bin" or "classes" folder after compilation):
URL fileURL = getClass().getClassLoader().getResource(fileName);
String fileName = fileURL.getFile();
String filePath = fileURL.getPath();

This depends a lot on what type of file you want to access. You can put the file in either assets or an appropriate subdirectory of res (see Difference between /res and /assets directories).

So you want to access a file internal to your app; and you want to do so directly, rather, that is, from an Android Context (and then with a [android.|<package_name>.]R.<resource_type>.<resource_name>).
You have two choices as to location: the res/raw folder or assets/ folder (outside of the res parent).
To choose between the two note from https://developer.android.com/guide/topics/resources/providing-resources.html
Arbitrary files to save in their raw form. To open these resources with a raw InputStream, call Resources.openRawResource() with the resource ID, which is R.raw.filename.
However, if you need access to original file names and file hierarchy, you might consider saving some resources in the assets/ directory (instead of res/raw/). Files in assets/ aren't given a resource ID, so you can read them only using AssetManager.
To access a file in res/raw/ directly rather, that is, from an Android Context (and then with a [android.|<package_name>.]R.<resource_type>.<resource_name>) you can do something like this:
File file = new File("app/src/main/res/raw/country_data_from_world_bank.xml");
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

Related

Random file from a folder inside JAR

I want to get a random image from a specific folder in Java. The code does already work inside the Eclipse IDE, but not in my runnable JAR. Since images inside the JAR file are not files, the code below results in a NullPointerException, but I'm not sure how to "translate" the code so that it will work in a runnable JAR.
final File dir = new File("images/");
File[] files = dir.listFiles();
Random rand = new Random();
File file = files[rand.nextInt(files.length)];
If the given path is invalid then listFiles() method reutrns null value. So you have to handle it if the path is invalid. Check below code:
final File dir = new File("images/");
File[] files = dir.listFiles();
Random rand = new Random();
File file = null;
if (files != null) {
file = files[rand.nextInt(files.length)];
}
If the jar is to contain the images then (assuming a maven or gradle project) they should be in the resources directory (or a subdirectory thereof). These images are then indeed no 'Files' but 'Resources' and should be loaded using getClass().getResource(String name) or getClass.getResourceAsStream(String name).
You could create a text file listing the resource paths of the images. This would allow you to simply read all lines from that file and access the resource via Class.getResource.
You could even create such a list automatically. The following works for my project type in eclipse; some minor adjustments may be needed for your IDE.
private static void writeResourceCatalog(Path resourcePath, Path targetFile) throws IOException {
URI uri = resourcePath.toUri();
try (BufferedWriter writer = Files.newBufferedWriter(targetFile, StandardCharsets.UTF_8)) {
Files.list(resourcePath.resolve("images")).filter(Files::isRegularFile).forEach(p -> {
try {
writer.append('/').append(uri.relativize(p.toUri()).toString()).append('\n');
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
writeResourceCatalog(Paths.get("src", "main", "resources"), Paths.get("src", "main", "resources", "catalog.txt"));
After building the jar with the new file included you could simply list all the files as
List<URL> urls = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(WriteTest.class.getResourceAsStream("/catalog.txt"), StandardCharsets.UTF_8))) {
String s;
while ((s = reader.readLine()) != null) {
urls.add(SomeType.class.getResource(s));
}
}
It seem like a path Problem, maybe will work if tried absolute path for image directory or set maon directory for java configuration

Java/Gradle: Override properties in Jar with external config.properties file [duplicate]

I'm trying to access a resource from a jar file. The resource is located in the same directory where is the jar.
my-dir:
tester.jar
test.jpg
I tried different things including the following, but every time the input stream is null:
[1]
String path = new File(".").getAbsolutePath();
InputStream inputStream = this.getClass().getResourceAsStream(path.replace("\\.", "\\") + "test.jpg");
[2]
File f = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
InputStream inputStream = this.getClass().getResourceAsStream(f.getParent() + "test.jpg");
Can you give me some hints? Thanks.
If you are sure, that your application's current folder is the folder of the jar, you can simply call InputStream f = new FileInputStream("test.jpg");
The getResource methods will load stuff using the classloader, not through filesystem. This is why your approach (1) failed.
If the folder containing your *.jar and image file is in the classpath, you can get the image resource as if it was on the default-package:
class.getClass().getResourceAsStream("/test.jpg");
Beware: The image is now loaded in the classloader, and as long as the application runs, the image is not unloaded and served from memory if you load it again.
If the path containing the jar file is not given in the classpath, your approach to get the jarfile path is good.
But then simply access the file directly through the URI, by opening a stream on it:
URL u = this.getClass().getProtectionDomain().getCodeSource().getLocation();
// u2 is the url derived from the codesource location
InputStream s = u2.openStream();
Use this tutorial to help you create a URL to a single file in a jar file.
Here's an example:
String jarPath = "/home/user/myJar.jar";
String urlStr = "jar:file://" + jarPath + "!/test.jpg";
InputStream is = null;
try {
URL url = new URL(urlStr);
is = url.openStream();
Image image = ImageIO.read(is);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch(Exception IGNORE) {}
}

URI not hierarchical need to use File class for a method

I need to open a video file with my code, and it works perfectly fine in Eclipse but when I export into a runnable JAR, i get an error "URI not hierarchical".
I have seen people suggest using getResourceAsStream(), but i need to have a file object as i am using Desktop.getDesktop.open(File). Can anyone help me out?
Here is the code:
try {
URI path1 = getClass().getResource("/videos/tutorialVid1.mp4").toURI();
File f = new File(path1);
Desktop.getDesktop().open(f);
} catch (Exception e) {
e.printStackTrace();
}
if it helps my folder list is like
Src
videos
videoFile.mp4
EDIT:
I plan to run this on windows only, and use launch4j to create an exe.
You can copy the file from the jar to a temporary file and open that.
Here's a method to create a temporary file for a given jar resource:
public static File createTempFile(String path) {
String[] parts = path.split("/");
File f = File.createTempFile(parts[parts.length - 1], ".tmp");
f.deleteOnExit();
try (Inputstream in = getClass().getResourceAsStream(path)) {
Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
return f;
}
And here's an example of how you'd use it:
Desktop.getDesktop().open(createTempFile("/videos/tutorialVid1.mp4"));

Access a resource outside a jar from the jar

I'm trying to access a resource from a jar file. The resource is located in the same directory where is the jar.
my-dir:
tester.jar
test.jpg
I tried different things including the following, but every time the input stream is null:
[1]
String path = new File(".").getAbsolutePath();
InputStream inputStream = this.getClass().getResourceAsStream(path.replace("\\.", "\\") + "test.jpg");
[2]
File f = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
InputStream inputStream = this.getClass().getResourceAsStream(f.getParent() + "test.jpg");
Can you give me some hints? Thanks.
If you are sure, that your application's current folder is the folder of the jar, you can simply call InputStream f = new FileInputStream("test.jpg");
The getResource methods will load stuff using the classloader, not through filesystem. This is why your approach (1) failed.
If the folder containing your *.jar and image file is in the classpath, you can get the image resource as if it was on the default-package:
class.getClass().getResourceAsStream("/test.jpg");
Beware: The image is now loaded in the classloader, and as long as the application runs, the image is not unloaded and served from memory if you load it again.
If the path containing the jar file is not given in the classpath, your approach to get the jarfile path is good.
But then simply access the file directly through the URI, by opening a stream on it:
URL u = this.getClass().getProtectionDomain().getCodeSource().getLocation();
// u2 is the url derived from the codesource location
InputStream s = u2.openStream();
Use this tutorial to help you create a URL to a single file in a jar file.
Here's an example:
String jarPath = "/home/user/myJar.jar";
String urlStr = "jar:file://" + jarPath + "!/test.jpg";
InputStream is = null;
try {
URL url = new URL(urlStr);
is = url.openStream();
Image image = ImageIO.read(is);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch(Exception IGNORE) {}
}

How to get the absolute path of a file in my project (and not of a file stored in a temporary folder)

I am using:
Eclipse Java EE IDE for Web Developers version: Mars.2 Release (4.5.2);
Apache Tomcat v8.0;
a Web Dynamic project;
a Java Servlet.
I have a JSON file stored in the ./WebContent folder. I am trying to get the absolute path of the JSON file in this way:
ServletContext sc = request.getSession().getServletContext();
//String absolutePath = "/Users/kazuhira/Documents/MAC_workspace/lab2_calendario/WebContent/Database/Events.json";
String relativePath = "eventsBackup.json";
String filePath = sc.getRealPath(relativePath);
System.out.println("(saverServlet): the path of the file is "+filePath);
//System.out.println("(saverServlet): the path of the file is "+absolutePath);
//File file = new File(absolutePath);
String content = request.getParameter("jsonEventsArray");
try (FileOutputStream fop = new FileOutputStream(file)) {
System.out.println("(saverServlet): trying to access to the file"+filePath);
// if file doesn't exists, then create it
if (!file.exists()) {
System.out.println("(saverServlet): the file doesn't exists");
file.createNewFile();
System.out.println("(saverServlet): file "+filePath+" created");
}
System.out.println("(saverServlet): writing on the file "+filePath);
// get the content in bytes
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
System.out.println("(saverServlet): events backup done");
} catch (IOException e) {
e.printStackTrace();
}
and the file path reconstructed from the relativePath is:
/Users/kazuhira/Documents/MAC_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/lab2_calendario/testJson.txt
Why String filePath = sc.getRealPath(relativePath); generates a path on a temporary folder? In which way I can configure the context on the "real" json file (the same I create in the project)?
I suppose Tomcat is working in a temporary context, why? There's a way to tell him to use the same folder of the project?
Yes, you can by changing an option in your Server configuration in Eclipse
Select the second option in the radio button list :)

Categories