Java & JTar - how to add a file inside a folder using JTar? - java

Windows - I am trying to create a new Tar file with with the JTar lib with the following inside...
MyTarFile.tar--|
|--MyFolder--|
|--MyFile.zip
I can create it with the folder and the zip file right in the root of MyTarFile but I don't know (and I looked around) how to create that folder AND have the zip file inside. I need to know what to use (the File object(s)) for the TarEntry(s) (is it one for folder and one for file...or one for both?) and what the InputStream should look like (I believe just a single one for the zip file but not sure). I am trying to create a file to mimic an existing format so I don't have the option of just losing that folder as the software that uses the file will be looking for it. I can add the zip file to the MyFolder folder on the actual file system (again, this is on Windows) before tarring or not...whatever works is fine.
I have tried full paths and relative paths (seems the InputStream MUST have a full path though) with no luck. Running out of ideas other than switching libraries (perhaps JTar doesn't support this).
Thanks!

Without seeing what you have already written, here is my best attempt at answering. I am unfamiliar with JTar, but after taking a look at the example on their main page, I wrote a quick test program that created a tar with one file in the root of the tar and one file in a directory in the tar, which I believe is what you are attempting to do. The code of interest to you is this:
TarEntry tarEntry = new TarEntry(new File("/Users/userGuy/Documents/students.xml"),"students.xml");
TarEntry otherTarEntry = new TarEntry(new File("/Users/userGuy/Documents/students2.xml"),"inner-dir/students2.xml");
Note that the second tar entry, otherTarEntry is instantiated with a relative path as the entryName argument in the TarEntry constructor. This is a poorly named argument, as it is technically the path of the file in the tar, not just the name.
With your example file names above, your code might look something like this:
TarEntry tarEntry = new TarEntry(new File("<path to file>"),"MyFolder/MyFile.zip");

Related

How do you create a file within a Java artifact?

I am currently working on a Java application in Intellij, and I cannot create a file within my artifact. As an example, I'm using File to create a file within the source, which is MainMenuData.txt.
File mainMenu = new File("MainMenuData.txt");
String absPath = mainMenu.getPath();
mainMenu.createNewFile();
BufferedReader br = new BufferedReader(new FileReader(absPath));
In this, I'm using File to make sure that file exists whenever it isn't.
Instead, I'd like to build within the (Production) artifact. Is that doable?
Anything helps. Thanks.
You could do that.
I assume your artifact is a jar file, which is nothing else than a zip file. You can obtain the location of your jar file in the file system and use the Zip File System to modify it. However I'm not sure, if the jvm might have a problem with that and it might not work on windows, since windows likes to block files, that are in use.
Also this would definitely fail, if your jar file is not stored locally.
A better approach would be to store your data files at the appropriate location in your system.
On Linux(and probably mac): <home>/.local/share/<your application name>/
On Linux(global): /var/lib/<application name>
On Windows(I think, better check it yourself): <appdata>/<your application name>
Your code would look something like this(for Linux):
File home = new File(System.getProperty("HOME");
File configDirectory = new File(home, ".local/share/<application name>");
configDirectory.mkdirs();
File mainMenu = new File(configDirectory, "MainMenuData.txt");
For windows do something similar. If you need both, you should check on which you are currently running.

How to read a file from a different folder than the project

I'm trying to read a txt file that is in a folder called "levels". The class where I'm using the Scanner is in src/anotherPackageName, if that's relevant. When I execute:
Scanner s = new Scanner(new File("levels/level0")); //adding .txt doesn't fix
it throws an exception. I don't want to use an absolute path, but rather relative to the project if possible. This is my folder structure:
D:\OneDrive\Folder\AnotherFolder\ProjectName
ProjectName
src
packageOne
ClassWhereImUsingScanner
OtherClasses
(...)
levels
level0
level1
(...)
So in order to access a file you could do something like this:
FileReader sourceFile = new FileReader("levels/level0.txt");
BufferedReader inStream = new BufferedReader(sourceFile);
String Line = inStream.readLine();
Then, you can use a tokenizer depending on your data and how you want to store it.
You could see this example: http://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/
Bear in mind that in most Java code, the end state of the project is not run from the IDE, but rather from some production system (e.g. an app or a server). In that case, your development source code structure won't be available.
There are two main ways to read text files or other resources in Java: either you can find the path to the actual file, in which case you need to deal with possibly not running out of your development source tree, or else you need to find a way to bundle the text file into your project.
Most Java projects end up getting compiled into some kind of archive, either a JAR file or a WAR file (for web applications) or something like an Android APK. In most cases you can add your own text files into the project archive. (For example, in a Maven project, if you just put your text file in the src/main/resources folder it should be included in the compiled JAR.)
However, in this case, the text file is no longer a separate file on disk, but rather a blob of data inside an archive. You could unzip the archive to get an actual File object, but that's wasteful if all you actually need is to read the bytes.
Thus, the most common way that text files like this are read is by using the existing ClassLoader mechanism, which is what is reading the .class files from disk (or from an archive, or over the network, or whatever). The ClassLoader already knows how to load bytes that are "alongside" your compiled code, so you can just make use of that.
In your case, you should be able to do something like this:
Scanner scanner = new Scanner(
getClass().getResourceAsStream("/path/to/file.txt"));
In this case, the /path/to/file.txt path is relative to the path your class was loaded from. E.g. if your class is named my.package.Foo then the actual class bytes will be in a folder (either a filesystem folder or in a JAR file or something) named my/package/Foo.class -- in this case, the path/to/file.txt and my/package/Foo.class will be relative to the same root.
See the documentation on resources for more information.
Usually the path is relative to your execution, but it also depends on your project setup on eclipse, could you send more information about you directory structure?
Based on you structure try something like this:
Scanner s = new Scanner(new File("../levels/level0"));

Reading txt files within a jar

I've already looked at many other questions that are similar to mine, but unfortunately none of their answers have so far worked.
I have a Java project that looks like this:
MyProject/
src/
abc/
MyClass.java
xyz/
file1.txt
file2.txt
...
Essentially, I'm trying to read all of the txt files above in MyClass.java. This is what I'm currently doing:
File dir = new File("src/xyz/");
for (File child : dir.listFiles()) {
...
}
This works fine until I put everything into a JAR format, at which point dir.listFiles() returns null and the above no longer works. Is there anyway I can still read these txt files even when they are packed into a JAR? Also, I am using Eclipse if it makes any difference.
You can access files on your classpath via the classloader.
getClass().getResourceAsStream("/xyz/file1.txt");
Then you would use the InputStream as usual. Note that I use absolute path, but relative to the current package works as well.
Since Java 6 it is also possible to list all the resources under a package quite easily:
Enumeration urls = getClass().getClassLoader().getResources("xyz");
urls.nextElement().openStream();
Is there anyway I can still read these txt files even when they are packed into a JAR?
Given you mean 'without knowing their names in advance' no.
OTOH you can include a resource at a known location in a Jar and list the possibles texts in that. Path from root or class-path, one per line would work well. Gain an URL to the resource using something like:
URL url = this.getClass().getResource("/path/to/the.resource");

Eclipse-Java: where to put file for Read purpose

I'm programming Java in Eclipse IDE. Here is code I want to read file:
File file = new File("file.txt");
reader = new BufferedReader(new FileReader(file));
I put file.txt in two place:
1) same folder of this SOURCE file.
2) in bin\...\ (same folder of this CLASS file)
But I allways receive NO FILE FOUND.
Please help me.
thanks :)
If the file ships with your application, it would be better accessed as a resource than as a file. Simply copy it to somewhere in your build path and use Class.getResourceAsStream or ClassLoader.getResourceAsStream. That way you'll also be able to access it if you bundle your app as a jar file.
Currently, you're looking for the file relative to the process's current working directory, which could be entirely unrelated to where the class files are.
if you put the file under sources and inside the package "test" for example, the path is:
./src/test/file.txt
you can use
File file = new File("./src/test/file.txt");
System.out.println(file.exists());
The path ./bin/test/file.txt will work in the second case and is more suitable for a normal java project

Setting Path Directory on File Reader

I'm working with text files on Java. On Ubuntu 10.
But, I'm having problems with path dir.
Example:
saveFile("textFile.txt","abc");
This abstract function basically put "abc" on "textFile.txt".
I compile this file, and create a jar file (using NetBeans).
When I run the app, and call saveFile("textFile.txt","abc"), textFile.txt is saved on \home. I don't want this. I want that textFile.txtgo to pathDir inside jar file.
How do I write in this file, this same way?
When reading resources from a JAR file, you cannot use the File API. Instead, you use Class.getResourceAsStream(), like this:
reader = new InputStreamReader(MyClass.class.getResourceAsStream(
"/apathdir/textFile.txt"), "UTF-8");
Note also how the encoding is specified. FileReader does not allow that, which is why it should usually be avoided.
Iwant to know, if fileName =
"textFile.txt", what is the path dir
of this file?
If you only use a bare file name (without giving a directory), the JVM will look for the file in the current directory of the JVM process; that is usually the directory you ran the JVM (the java executable) from.
how do i do to set
/apathdir/textFile.txt?. apathdir is a
directory that is inside jar file.
I tried: fileName = "/apathdir/textFile.txt", but doesn't works.
If you want to load a file from inside a JAR file, you cannot load it using FileReader. You need to use ClassLoader.getSystemResourceAsStream() (or Class.getResourceAsStream). See e.g. this article for an explanation:
http://www.devx.com/tips/Tip/5697

Categories