How can i get .txt file in my jar? - java

I want to say I search a lot even google and stackoverflow. There are many topics about this but I dont find exactly what I need.
My problem is :
I want to define file which is in my own package folder.File's format is .txt.
And file is in xxx\src\xxxx\myTXTFile.txt
I write this code to reach my txt:
File f = new File(xxx.class.getResource("pr.txt").getFile());
When I run this code on netbeans yes it works.But when I compile and click .jar file it reports:
File not found
What can I do?

In the IDE the file still resides also outside the zip-format jar. Hence was found. For files inside the jar use:
OutputStream f = xxx.class.getResourceAsStream("pr.txt");
File does not work.

You can reach your txt-File with this code:
File f = new File("xxxx/myTXTFile.txt");
or you must save your txtfile in a Tempfolder:
InputStream is = getClass().getClassLoader().getResourceAsStream("xxxx/myTXTFile.txt");
OutputStream os = new FileOutputStream(new File("/tmp/tempTXTFile.txt"));
while ((i = is.read(buffer)) != -1)
{
output.write(buffer, 0, i);
}
output.close();
is.close();
File f = new File("/tmp/tempTXTFile.txt");

Related

EFFICIENTLY Load classes from jar file INSIDE jar file

Java programmer here.
I'm trying to make a "plugin system" in java, and I would like ot make it so that the user can import their own java libraries if they needed to so they are not limited to only have my plugin loading application in their build path.
I was planning on allowing the user to make a folder called "lib" in their project, which is where they would put all the other libraries they needed, so they can then add those to the build path with the application erroring when loading all the necessary plugins. But, I am having trouble to do so.
Here is an example plugin jar file I have, that is structured the way I want it to be:
Plugin.jar
|---org
|---pluginpackage
|---PluginMainClass.class
|---lib
|---user-lib.jar
|---libpackage
|---InterfaceA.class
|---ClassB.class
|---...
|---plugin-description.xml
What I was wondering is this: What would be the most efficient way to load all the libraries the user has loaded inside the "lib" folder?
This is the current code I have, but it takes longer than desired to load the libraries:
private void readLibraryInJar(JarInputStream jarLibraryInputStream, File dirOut) throws IOException {
if (jarLibraryInputStream == null)
return;
JarEntry entry = null;
while ((entry = jarLibraryInputStream.getNextJarEntry()) != null) {
final String jarPath = entry.getName().trim();
if (jarPath.endsWith(".class")) {
File f = new File(dirOut, jarPath);
if (!f.exists()) {
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
}
f.createNewFile();
}
byte[] buffer = new byte[1024 * 100];
FileOutputStream out = new FileOutputStream(f);
int len;
while ((len = jarLibraryInputStream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.close();
}
}
}
The above code reads each class file inside the desired library and copy's its content's into a new file. I know that a more efficient way is out there somewhere (e.g. Apache Tomcat project can have a "lib" folder), so I was wondering if I could load the library jar file more effeciently than I currently do (planning on using URLClassLoader to load it, so if you could transform it into a URL that would be awesome, but if that is impossible, I am still okay with any way more efficient than my current one.)
Thanks in advance!

Cannot Find Path Specified Creating File Despite Existing Parent Directory

I am trying to export zip files to a directory and running into an IOException stating that the file path cannot be found. I am aware that this means that the parent directory does not exist usually, however debugging the line where the file is being written file.getParentFile().exists() returns true, so this is not my issue. To further complicate matters, this only occurs for approximately half of the files written. It is always the same files that fail when unzipping via java, but unzipping them via windows always successfully works.
Here is the code I am using:
ZipInputStream zis =
new ZipInputStream(new ByteArrayInputStream(zipFile));
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
if(!newFile.isDirectory()) {
newFile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(newFile); //Exception occurs here
//newFile.getParentFile().exists() returns true
//copying the path for newFile.getParentFile() into my file browser leads me to a valid, existing folder
//I have tried newFile.createNewFile() and that errors with a similar exception
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
results.add(new Foo());
}
ze = zis.getNextEntry();
}
Example exception:
java.io.FileNotFoundException: \\foo\foo\foo\foo\foo\foo\foo.pdf (The system cannot find the path specified)
Some more notes about the system: the file system is a remote network drive, the system is running windows, and the account has full write access to the drive. I have also verified that naming a file foo.pdf (copy and pasting the name of the file intended to be written) does not cause any issue either.
The issue is that zip files can have trailing spaces in their paths. For example, "Test whatever .zip" could be the file name so java sees the folder as "/Test whatever /" and it tries to create that folder. Windows tells java that it succeeded, but really it created a folder at "/Test Whatever/". When dealing with folders, the file IO has no issue with this, but when writing files, it completely bombs as it's looking for the path explicitly. It does not truncate the extra white space the same way it does when dealing with folders, as you would expect.
Here is the code I used to resolve it:
String path = (outputFolder + File.separator + fileName).replace(" ", "");
File newFile = new File(path);

Extract Files from Java project, during run proccess

I am trying to extract few files contained in the java project into a certain path, lets say "c:\temp".
I tried to use this example :
String home = getClass().getProtectionDomain().
getCodeSource().getLocation().toString().
substring(6);
JarFile jar = new JarFile(home);
ZipEntry entry = jar.getEntry("mydb.mdb");
File efile = new File(dest, entry.getName());
InputStream in =
new BufferedInputStream(jar.getInputStream(entry));
OutputStream out =
new BufferedOutputStream(new FileOutputStream(efile));
byte[] buffer = new byte[2048];
for (;;) {
int nBytes = in.read(buffer);
if (nBytes <= 0) break;
out.write(buffer, 0, nBytes);
}
out.flush();
out.close();
in.close();
I think I am doing it wrong and, this code probably looking for a specific jar but not in my project directory. I prefer to figure a way that can retrieve my files from resources package, inside the project folder and extract it to specific folder i choose.
I am using Eclipse, 1.4 J2SE library.
Well, it's hard to guess what's wrong without any code examples.
But as for pair of random guesses I could tell that sometimes you get this kind of error when the file is locked by earlier instance of your program which is still running. Make sure you've got only one running instance of Eclipse.
Also you can try to refresh the project folder by right click --> refresh to sync your file system with Eclipse's internal file system: when it comes to Eclipse, multiple refresh/rebuild someway magically solves project problems :)

How to obtain File handle to a resource on runtime classpath?

I have a situation where I need to scan the runtime classpath for a resource file (say, res/config/meta.cfg), and then create a File handle for it. The best I've been able to come up with is:
// This file is located inside a JAR that is on the runtime classpath.
String fileName = "res/config/meta.cfg";
try {
InputStream inStream = ClassLoader.getSystemResourceAsStream(fileName);
File file = new File(String.format("${java.io.tmpdir}/%s", fileName));
FileOutputStream foutStream = null;
foutStream = new FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while((read = inStream.read(bytes)) != -1)
foutStream.write(bytes, 0, read);
foutStream.close();
return file;
} catch (Exception exc) {
throw new RuntimeException(exc);
}
So essentially, read in the resource as an InputStream, and then write the stream to a temp file (under {$java.io.tmpdir}) so that we can obtain a valid File handle for it.
This seems like going 3 sides around the barn. Is there a better/easier/more elegant way of doing this? Thanks in advance!
No.
Of course you can (and probably should) use a library to copy the InputStream's content to a file but that obviously is not the point of your question.
The classpath does not consist of directories only; resources can be inside archives (typically JARs) or on servers, and may not exist as something that can be accessed via a java.io.File object.
Typically the core problem is to use java.io.File objects where an InputStream would be sufficient. Sometimes you can't do anything against it when using a third-party library but it is a hint that the library designers didn't work very carefully. If you need the file handle in your own code you should have another look why it can't be an InputStream. Most of the time it can.

zip a folder structure using java

I am trying to zip the following file structure on my machine,
parent/
parent/test1
parent/test1/image1.jpeg
parent/test2
The problem here is i cant zip the above file structure using java. I have google and found following code sample but it only zip the files only inside a given folder.
File inFolder=new File("out");
File outFolder=new File("Out.zip");
ZipOutputStream out = new ZipOutputStream(new
BufferedOutputStream(new FileOutputStream(outFolder)));
BufferedInputStream in = null;
byte[] data = new byte[1000];
String files[] = inFolder.list();
for (int i=0; i<files.length; i++)
{
in = new BufferedInputStream(new FileInputStream
(inFolder.getPath() + "/" + files[i]), 1000);
out.putNextEntry(new ZipEntry(files[i]));
int count;
while((count = in.read(data,0,1000)) != -1)
{
out.write(data, 0, count);
}
out.closeEntry();
}
out.flush();
out.close();
In the above code the out is a folder and we need to have some files..also folder cannot be empty if so it throws a exception java.util.zip.ZipException or cant contain any sub folders even files inside it (eg:out\newfolder\image.jpeg) if so it throws a java.io.FileNotFoundException: out\newfolder (Access is denied).
In my case im costructig the above file structure by quering the database sometime empty folders along the folder structure can be have.
Can some one please tell me a solution?
Thank You.
What is probably happening is that you're trying to treat every entry as a FileInputStream. However, for a directory, this is not true. Since the path is not to a file, when you try to read it, a FileNotFoundException is thrown. For directories, you still want to create the ZipEntry, but instead of trying to read in any data, just skip it and move on to the next path.
write two methods. The first one takes dirpath, makes a zip stream and calls another method which copies files to the zip stream and calls itself recursively for directories as below:
open an entry in the zip stream for the given directory
list files and dirs in the given directory, loop through them
if an entry is a file, open an entry, copy file content to the entry, close it
if an entry is a directory, call this method. Pass the zip stream
close the entry.
The first method closes the zip stream.

Categories