How to name a file from a folder in java? - java

I have a file named InputFile.txt in a resources folder.
My project structure is like this:
VirtualMemory
src
resources
InputFile.txt
VirtualMemory
VirtualMemory.java
And I am trying to access the InputFile.txt in VirtualMemory.java class by like this:
String filename = ("./src/resources/InputFile.txt");
File file = new File(filename);
But the file is not being found. How to resolve this problem?

Below code will help load a properties file from any where in the classpath.
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
URL url = cl.getResource(CONF_PROPERTIES);
if (url == null) {
url = cl.getResource("/" + CONF_PROPERTIES);
}
if (url != null) {
try {
InputStream in = url.openStream();
props = new Properties();
props.load(in);
} catch (IOException e) {
// Log the exception
} finally {
// close opened resources
}
}
}

Related

Jar executable of spring app file upload failed?

This spring app performs simple file upload,
here's the controller class
#Override
public String fileUpload(MultipartFile file) {
try{
// save uploaded image to images folder in root dir
Files.write(Paths.get("images/"+ file.getOriginalFilename()), file.getBytes());
// perform some tasks on image
return "";
} catch (IOException ioException) {
return "File upload has failed.";
} finally {
Files.delete(Paths.get("images/" + file.getOriginalFilename()));
}
}
but when i build jar and runs, it throws IOException saying,
java.nio.file.NoSuchFileException: images\8c9.jpeg.
So my question is how can i add the images folder inside the jar executable itself.
Thanks.
You should provide a full path for the images folder, or save in java.io.tmpdir creating the image folder first.
But, in my opinion you should configure your upload folder from a config file for flexibility. Take a look at this.
app:
profile-image:
upload-dir: C:\\projs\\web\\profile_image
file-types: jpg, JPG, png, PNG
width-height: 360, 360
max-size: 5242880
In your service or controller, do whatever you like, may be validate image type, size etc and process it as you like. For instance, if you want thumbnails(or avatar..).
In your controller or service class, get the directory:
#Value("${app.image-upload-dir:../images}")
private String imageUploadDir;
Finally,
public static Path uploadFileToPath(String fullFileName, String uploadDir, byte[] filecontent) throws IOException {
Path fileOut = null;
try{
Path fileAbsolutePath = Paths.get(StringUtils.join(uploadDir, File.separatorChar, fullFileName));
fileOut = Files.write(fileAbsolutePath, filecontent);
}catch (Exception e) {
throw e;
}
return fileOut; //full path of the file
}
For your question in the comment: You can use java.io.File.deleteOnExit() method, which deletes the file or directory defined by the abstract path name when the virtual machine terminates. TAKE A GOOD CARE THOUGH, it might leave some files if not handled properly.
try (ByteArrayOutputStream output = new ByteArrayOutputStream();){
URL fileUrl = new URL(url);
String tempDir = System.getProperty("java.io.tmpdir");
String path = tempDir + new Date().getTime() + ".jpg"; // note file extension
java.io.File file = new java.io.File(path);
file.deleteOnExit();
inputStream = fileUrl.openStream();
ByteStreams.copy(inputStream, output); // ByteStreams - Guava
outputStream = new FileOutputStream(file);
output.writeTo(outputStream);
outputStream.flush();
return file;
} catch (Exception e) {
throw e;
} finally {
try {
if(inputStream != null) {
inputStream.close();
}
if(outputStream != null) {
outputStream.close();
}
} catch(Exception e){
//skip
}
}

java.io.IOException: Stream closed accessing config files outside of jar folders

I'm executing a jar file which reads configs from a config file outside of /home/user/xxx/testFolder/jarfile, the path of config file is /opt/xxx/conf/global_config.cfg.
However, I'm able to access files inside the jar, so I assume the error is due to the file not being found.
Below is my code:
public Properties createProperties(){
Properties p = null;
ClassLoader cl = this.getClass().getClassLoader();
try (InputStream stream = cl.getResourceAsStream("/opt/xxx/conf/global_config.cfg")) {
p = new Properties();
BufferedInputStream bis = new BufferedInputStream(stream);
p.load(bis); // this is throwing the error
System.out.println(p.toString());
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
What is the correct way of getting a file regardless of its path in a Linux system?
cl.getResourceAsStream("/opt/xxx/conf/global_config.cfg")
expects the resource to be available in relation to the class location. So, it will search as a relative path to the class inside the JAR. But the path /opt/xxx/conf/global_config.cfg is a absolute disk path, and for reading it , you need to use the FileInputStream
public Properties createProperties(){
Properties p = null;
ClassLoader cl = this.getClass().getClassLoader();
try (InputStream stream =new FileInputStream("/opt/xxx/conf/global_config.cfg")) {
p = new Properties();
p.load(stream);
System.out.println(p.toString());
} catch (IOException e) {
e.printStackTrace();
}
return p;
}

How to access /data folder of another application through your application?

there is a text file that an application produces, I would like to take that file and read it as strings in my application. How can I achieve that, any help would be grateful. Both applications are my applications so I can get the permissions.
Thank you!
This is possible using the standard android-storage, where all the user's files are stored too:
All you need to do is to access the same file and the same path in both applications, so e.g.:
String fileName = Environment.getExternalStorageDirectory().getPath() + "myFolderForBothApplications/myFileNameForBothApplications.txt";
Where myFolderForBothApplications and myFileNameForBothApplications can be replaced by your folder/filename, but this needs to be the same name in both applications.
Environment.getExternalStorageDirectory() returns a File-Object to the common, usable file-directory of the device, the same folder the user can see too.
By calling the getPath() method, a String representing the path to this storage is returned, so you can add your folder/filenames afterwards.
So a full code example would be:
String path = Environment.getExternalStorageDirectory().getPath() + "myFolderForBothApplications/";
String pathWithFile = path + "myFileNameForBothApplications.txt";
File dir = new File(path);
if(!dir.exists()) { //If the directory is not created yet
if(!dir.mkdirs()) { //try to create the directories to the given path, the method returns false if the directories could not be created
//Make some error-output here
return;
}
}
File file = new File(pathWithFile);
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
//File couldn't be created
return;
}
Afterwards, you can write in the file or read from the file as provided e.g. in this answer.
Note that the file stored like this is visible for the user and my be edited / deleted by the user.
Also note what the JavaDoc for the getExternalStorageDirectory() says:
Return the primary external storage directory. This directory may not currently be accessible if it has been mounted by the user on their computer, has been removed from the device, or some other problem has happened. You can determine its current state with getExternalStorageState().
I do not know if this is the best/safest way to fix your problem, but it should work.
You can save the text file from your assets folder to anywhere in the sdcard, then you can read the file from the other application.
This method uses the getExternalFilesDir, that returns the absolute path to the directory on the primary shared/external storage device where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(Environment.getExternalStorageDirectory(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
And to read:
File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, "path/to/the/file/inside/the/sdcard.ext");

How to get the path of executed .jar file?

How do I get the path of a an executed .jar file, in Java?
I tried using System.getProperty("user.dir"); but this only gave me the current working directory which is wrong, I need the path to the directory, that the .jar file is located in, directly, not the "pwd".
Could you specify why you need the path?If you need to access some property from the jar file you should have a look at ClassLoader.getSystemClassLoader();
don't forget that your classes are not necessary store in a jar file.
// if your config.ini file is in the com package.
URL url = getClass().getClassLoader().getResource("com/config.ini");
System.out.println("URL=" + url);
InputStream is = getClass().getClassLoader().getResourceAsStream("com/config.ini");
try {
if (is != null) {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
else {
System.out.println("resource not found.");
}
}
catch (IOException e) {
e.printStackTrace();
}
regards.
Taken From Java-Forumns:
public static String getPathToJarfileDir(Object classToUse) {
String url = classToUse.getClass().getResource("/" + classToUse.getClass().getName().replaceAll("\\.", "/") + ".class").toString();
url = url.substring(4).replaceFirst("/[^/]+\\.jar!.*$", "/");
try {
File dir = new File(new URL(url).toURI());
url = dir.getAbsolutePath();
} catch (MalformedURLException mue) {
url = null;
} catch (URISyntaxException ue) {
url = null;
}
return url;
}
Perhaps java.class.path property?
If you know the name of your jar file, and if it is in the class path, you can find its path there, eg. with a little regex.

Reading properties file from JAR directory

I’m creating an executable JAR that will read in a set of properties at runtime from a file. The directory structure will be something like:
/some/dirs/executable.jar
/some/dirs/executable.properties
Is there a way of setting the property loader class in the executable.jar file to load the properties from the directory that the jar is in, rather than hard-coding the directory.
I don't want to put the properties in the jar itself as the properties file needs to be configurable.
Why not just pass the properties file as an argument to your main method? That way you can load the properties as follows:
public static void main(String[] args) throws IOException {
Properties props = new Properties();
props.load(new BufferedReader(new FileReader(args[0])));
System.setProperties(props);
}
The alternative: If you want to get the current directory of your jar file you need to do something nasty like:
CodeSource codeSource = MyClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
File jarDir = jarFile.getParentFile();
if (jarDir != null && jarDir.isDirectory()) {
File propFile = new File(jarDir, "myFile.properties");
}
... where MyClass is a class from within your jar file. It's not something I'd recommend though - What if your app has multiple MyClass instances on the classpath in different jar files (each jar in a different directory)? i.e. You can never really guarantee that MyClass was loaded from the jar you think it was.
public static void loadJarCongFile(Class Utilclass )
{
try{
String path= Utilclass.getResource("").getPath();
path=path.substring(6,path.length()-1);
path=path.split("!")[0];
System.out.println(path);
JarFile jarFile = new JarFile(path);
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
if (entry.getName().contains(".properties")) {
System.out.println("Jar File Property File: " + entry.getName());
JarEntry fileEntry = jarFile.getJarEntry(entry.getName());
InputStream input = jarFile.getInputStream(fileEntry);
setSystemvariable(input);
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Jar file"+line);
}
reader.close();
}
}
}
catch (Exception e)
{
System.out.println("Jar file reading Error");
}
}
public static void setSystemvariable(InputStream input)
{
Properties tmp1 = new Properties();
try {
tmp1.load(input);
for (Object element : tmp1.keySet()) {
System.setProperty(element.toString().trim(),
tmp1.getProperty(element.toString().trim()).trim());
}
} catch (IOException e) {
System.out.println("setSystemvariable method failure");
}
}

Categories

Resources