I want to use the TrueZip library to append a file to an existing archive (not by
unpacking, adding a file and repacking - the new versions are supposed to have this
feature), but I find it a bit difficult to understand the API.
Can please someone, more knowledgeable than me, suggest how to do this in a few lines?
Google is your friend:
Appending entries to ZIP files with TrueZIP 7.3
class MyApplication extends TApplication {
#Override
protected void setup() {
// This should obtain the global configuration.
TConfig config = TConfig.get();
// Set FsOutputOption.GROW for appending-to rather than reassembling an
// archive file.
config.setOutputPreferences(
config.getOutputPreferences.set(FsOutputOption.GROW));
}
...
}
Related
I have written a project where some images are used for the application's appearance and some text files will get created and deleted along the process. I only used the absolute path of all used files in order to see how the project would work, and now that it is finished I want to send it to someone else. so what I'm asking for is that how I can link those files to the project so that the other person doesn't have to set those absolute paths relative to their computer. something like, turning the final jar file with necessary files into a zip file and then that the person extracts the zip file and imports jar file, when runs it, the program work without any problems.
by the way, I add the images using ImageIcon class.
I'm using eclipse.
For files that you just want to read, such as images used in your app's icons:
Ship them the same way you ship your class files: In your jar or jmod file.
Use YourClassName.class.getResource or .getResourceAsStream to read these. They are not files, any APIs that need a File object can't work. Don't use those APIs (they are bad) - good APIs take a URI, URL, or InputStream, which works fine with this.
Example:
package com.foo;
public class MyMainApp {
public void example() {
Image image = new Image(MyMainApp.class.getResource("img/send.png");
}
public void example2() throws IOException {
try (var raw = MyMainApp.class.getResourceAsStream("/data/countries.txt")) {
BufferedReader in = new BufferedReader(
new InputStreamReader(raw, StandardCharsets.UTF_8));
for (String line = in.readLine(); line != null; line = in.readLine()) {
// do something with each country
}
}
}
}
This class file will end up in your jar as /com/foo/MyMainApp.class. That same jar file should also contain /com/foo/img/send.png and /data/countries.txt. (Note how starting the string argument you pass to getResource(AsStream) can start with a slash or not, which controls whether it's relative to the location of the class or to the root of the jar. Your choice as to what you find nicer).
For files that your app will create / update:
This shouldn't be anywhere near where your jar file is. That's late 80s/silly windows thinking. Applications are (or should be!) in places that you that that app cannot write to. In general the installation directory of an application is a read-only affair, and most certainly should not be containing a user's documents. These should be in the 'user home' or possibly in e.g. `My Documents'.
Example:
public void save() throws IOException {
Path p = Paths.get(System.getProperty("user.home"), "navids-app.save");
// save to that file.
}
I'm using Apache Commons Compress to parse entries in a 7zip archive. I need to be able to find a specific file (e.g. "thisfile.xml"), I was wondering if there is a better way of doing it other than just looping through every entry in the archive.
The sort of thing I'm currently doing is this:
SevenZFile archive = new SevenZFile("chosen 7zip file");
for (SevenZArchiveEntry entry : sevenZFile.getEntries())
{
if (entry.getName().equals("Sites.xml"))
{
//Do stuff
break;
}
}
I don't particularly want to iterate over all entries in the archive, as there could be a lot of them.
Any ideas would be much appreciated
I have a bunch of public assets that I would like to zip and provide for download.
Is there an easy way in Play! to create a zip for a list of files/folders?
I suppose you can always use Java libraries. See JavaDocs for details
play war "project_dir" -o "war_file_name" --zip
Note: I'm using Play-1.2.3
You can use Play helper class, Files.zip
In the controller use this:
public class Public extends Controller {
public static void download() {
File dir = VirtualFile.fromRelativePath("/dir-to-zip/").getRealFile();
File zip = VirtualFile.fromRelativePath("/files.zip").getRealFile();
Files.zip(dir, zip);
renderBinary(zip);
}
}
Then add this to your routes file:
* /download Public.download
Note that file paths are from your application root, not your file system root.
I am making the library that has the default properties in the file default.properties.
private static String defPropertyPath = "/database.properties";
I want to ask if this file can be replaced by the program that use my library. So the program will define the properties with the same name default.properties that will replace the properties from library. I created the default.properties in the program where i use the library, but the library is still loading the properties from their package.
edit:
I read the properties file via input stream:
InputStream ins = DbProperties.class.getResourceAsStream(defPropertyPath);
if (ins == null) {
logger.error("Can't find properties:" + pathToProperties);
return;
}
Edit: File structure:
DbLibrary.jar
/
/database.properties
/src
MyApplication.jar
/
/database.properties
/src
/lib/DbLibrary.jar
My application use the DbLibrary.jar and wants to force this library to use database.properties from MyApplication and not from the DbLibrary.
May be much clearer if your library exports some API that allows the user of your library to invoke an init method at any time.
public static void init(Properties p) { ... }
I'm not sure there is enough information to answer your question, but I'm going to guess that perhaps you included the "database.properties" file in the jar with your application. If you did that, the application will always read the file from the jar, and not from the file system.
You only have to override the properties file in these projects which include your library.
Given
URL of an archive (e.g. a zip file)
Full name (including path) of a file inside that archive
I'm looking for a way (preferably in Java) to create a local copy of that file, without downloading the entire archive first.
From my (limited) understanding it should be possible, though I have no idea how to do that. I've been using TrueZip, since it seems to support a large variety of archive types, but I have doubts about its ability to work in such a way. Does anyone have any experience with that sort of thing?
EDIT: being able to also do that with tarballs and zipped tarballs is also important for me.
Well, at a minimum, you have to download the portion of the archive up to and including the compressed data of the file you want to extract. That suggests the following solution: open a URLConnection to the archive, get its input stream, wrap it in a ZipInputStream, and repeatedly call getNextEntry() and closeEntry() to iterate through all the entries in the file until you reach the one you want. Then you can read its data using ZipInputStream.read(...).
The Java code would look something like this:
URL url = new URL("http://example.com/path/to/archive");
ZipInputStream zin = new ZipInputStream(url.getInputStream());
ZipEntry ze = zin.getNextEntry();
while (!ze.getName().equals(pathToFile)) {
zin.closeEntry(); // not sure whether this is necessary
ze = zin.getNextEntry();
}
byte[] bytes = new byte[ze.getSize()];
zin.read(bytes);
This is, of course, untested.
Contrary to the other answers here, I'd like to point out that ZIP entries are compressed individually, so (in theory) you don't need to download anything more than the directory and the entry itself. The server would need to support the Range HTTP header for this to work.
The standard Java API only supports reading ZIP files from local files and input streams. As far as I know there's no provision for reading from random access remote files.
Since you're using TrueZip, I recommend implementing de.schlichtherle.io.rof.ReadOnlyFile using Apache HTTP Client and creating a de.schlichtherle.util.zip.ZipFile with that.
This won't provide any advantage for compressed TAR archives since the entire archive is compressed together (beyond just using an InputStream and killing it when you have your entry).
Since TrueZIP 7.2, there is a new client API in the module TrueZIP Path. This is an implementation of an NIO.2 FileSystemProvider for JSE 7. Using this API, you can access HTTP URI as follows:
Path path = new TPath(new URI("http://acme.com/download/everything.tar.gz/README.TXT"));
try (InputStream in = Files.newInputStream(path)) {
// Read archive entry contents here.
...
}
I'm not sure if there's a way to pull out a single file from a ZIP without downloading the whole thing first. But, if you're the one hosting the ZIP file, you could create a Java servlet which reads the ZIP file and returns the requested file in the response:
public class GetFileFromZIPServlet extends HttpServlet{
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
String pathToFile = request.getParameter("pathToFile");
byte fileBytes[];
//get the bytes of the file from the ZIP
//set the appropriate content type, maybe based on the file extension
response.setContentType("...");
//write file to the response
response.getOutputStream().write(fileBytes);
}
}