My requirement is to replace few files in a zip file.
The zip file in turn have multiple zip files and folder within it. It goes upto 4 or more levels of zip files.
I have a set of files in a different source directory. I would like to copy these files and replace within the zip file, by matching the file name in the source directory with file name inside the zip file.
Could someone help here please.
Thanks,
Deleep
One way is use temp files to store the ZIPs and open them as FileSystems, so you dont need to extrat all files and rezip everything
FileSystem firstZip = FileSystems.newFileSystem(URI.create("jar:file:/root/firstZip.zip"),
new HashMap<>(), null);
//Get a zip inside the first one
Path path = firstZip.getPath("FOLDER/ZIP_NAME.zip");
//Get the second zip input stream and store the zip in a temp file
InputStream in = firstZip.provider().newInputStream(path);
Path secondPath = Paths.get("/root/temp/tempFile.tmp");
Files.copy(in, secondPath);
//open the second zip
FileSystem secondZip = FileSystems.newFileSystem(new URI("jar:" + secondPath.toUri().toString()),
new HashMap<>(), null);
//iterate files in the second zip
DirectoryStream<Path> ds = Files.newDirectoryStream(secondPath);
for(Path p: ds){
//something
}
//delete or update files inside the second zip
//Files.delete(seconZip.getPath("aFile.txt"));
//Files.copy(anInputStream, secondZip.getPath("destFoldet/aFile.txt"));
//clse the seconzip
secondZip.close();
//update the second zip inside first one
Files.copy(secondPath, firstZip.provider().newOutputStream(path));
//delete temp file
Files.delete(secondPath);
//close first zip
firstZip.close();
Other idea is jboss-vfs. Never tried it, but i think that could help.
Related
We can determine the folder structure of a zip archive using python as follows (we can do the same in Java also):
with zipfile.ZipFile('path to file', 'r') as zipobj:
for item in zipobj.infolist():
print(item.filename)
However, is it possible to determine the folder structure of a particular folder inside the zip archive and iterate through all files/folders inside that folder (similar to the path object) only? (instead of iterating all files/folders inside the zip archive as shown in the previous code example)
You can read the file as ZipFile and then iterate over all the entries which are folders. Here is a code snippet in Java:
ZipFile zip = new ZipFile(file);
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.isDirectory()) {
// Code goes here
}
}
Reading a ZIP structure as Path components is very simple with Java NIO as there are built in handlers for ZIP filesystems - see FileSystems.newFileSystem(zip), and the Path objects it provides work with other NIO classes such as Files.
For example this scans a zip starting from folder org/apache, and you can substitute any other filters needed treating the ZIP structure just like any other disc filesystem:
try (FileSystem fs = FileSystems.newFileSystem(zip)) {
Path root = fs.getPath("org/apache");
try(Stream<Path> stream = Files.find(root, Integer.MAX_VALUE, (p,a) -> true)) {
stream.forEach(System.out::println);
}
}
Expected:
find the number files in the folder, and collect the absolute path for each file in the directory.
File certificatePath = new File("resources/NPL");
String absolutePath = certificatePath.getAbsolutePath();
File directory = new File(absolutePath);
int fileCount=directory.list().length;
From the above code getting the no of files in folder (resources/NPL), now i'm struggle to get the absolute path for the files.
You should use listFiles instead fo list() (provided you have the security rights to do so), otherwise you are stuck with the file names.
Well first of all what does it mean to collect it? If you need the file names it is already there for you in an array of String[] which you get from directory.list() method. If you want the full names you can use listFiles() method which returns a File[] and each file has getAbsolutePath() method. Something like:
for (File file : directory.listFiles()) {
System.out.println(file.getAbsolutePath());
}
I know how to create a temporary directory in Java, but is there an easy way to copy files in Java from the jar file to this directory?
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File helpDir = new File(tmpDir, "myApp-help");
helpDir.createNewFile(); // oops, this isn't right, I want to create a dir
URL helpURL = getClass().getResource("/help-info");
/* ???? I want to copy the files from helpURL to helpDir */
Desktop desktop = Desktop.getDesktop();
URI helpURI = /* some URI from the new dir's index.html */
desktop.browse(helpURI);
Apache's org.apache.commons.io.FileUtils can do that for you
To create directory use File.mkdir();
Convert URL to File with org.apache.commons.io.FileUtils.toFile(URL)
use org.apache.commons.io.FileUtils.copyFile() to copy.
You can make use of the command jar tf [here your jarfile]. This will list the contents of the JAR Archive with their full path, relative to the jarfile (1 line = 1 file). Check if the line starts with the path of the directory you want to extract, and use Class.getResourceAsStream(URL) for the matching lines and extract them to your temporary folder.
Here is an example output of jar tf:
META-INF/MANIFEST.MF
TicTacToe.class
audio/
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
images/
images/cross.gif
images/not.gif
I create zip file using ZipOutputStream. I put in the zip one file(both file and zip are in the same dir), however the file is stored with fullpath (C:\TEMP\file.xml), how to store it with relative or no path?
You need to set that in the ZipEntry. For example, if you don't want any path, just use the name of the file in your ZipEntry, like this:
File f = new File("C:\\temp\\file.xml");
ZipEntry entry = new ZipEntry(f.getName());
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.