Java: Files is not compressed properly(with file permission) - java

I have making zip file using java. hence, i had face a small problem. Execute files(*.sh and binary files) are compressed is not properly with his file permissions. pls find the following code for make zip
public static void makeZip(String compressDirPath, String zipName, String outputLoc)
throws java.io.IOException
{
if(outputLoc.equals("") || outputLoc == null) outputLoc = ".";
File compressDir = new File(compressDirPath);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outputLoc+"/"+zipName));
compress(compressDir, compressDir, zos);
zos.close();
}
private static void compress(File compressDir, File base, ZipOutputStream zos) throws java.io.IOException
{
File[] files = compressDir.listFiles();
byte[] buffer = new byte[18024];
int read = 0;
for (int i = 0, n = files.length; i < n; i++) {
if (files[i].isDirectory()) {
compress(files[i], base, zos);
} else {
FileInputStream in = new FileInputStream(files[i]);
ZipEntry entry = new ZipEntry(files[i].getPath().substring(base.getPath().length() + 1));
zos.putNextEntry(entry);
while (-1 != (read = in.read(buffer))) { zos.write(buffer, 0, read); }
in.close();
}
}
}
When i have unzip the zipped file, execute files create by normal file. How can i solve this problem?

As far as I get it, file permissions are not stored within zip archives. You can use a tar archive instead. See JTar or org.apache.tools.tar.

Related

How to zip a file and split with a max size limit using java

I need to zip a 30MB file into different zip files which have a limit of 5MB per zip file.
My work will stop to zip after the size is larger than the limit now. I referenced and tried some examples but made me feel confused.
Please give me suggestions. Thank you.
public static void zipDirectory(File dir, File zipFile, boolean contentOnly)
throws IOException {
synchronized (syncObj) {
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
if (contentOnly)
zipSubDirectory("", dir, zout);
else
zipSubDirectory(dir.getName() + "/", dir, zout);
zout.close();
}
}
private static void zipSubDirectory(String basePath, File dir,
ZipOutputStream zout) throws IOException {
synchronized (syncObj) {
byte[] buffer = new byte[4096];
final long MAX_ZIP_SIZE = 5000000;
long currentSize = 0;
int zipSplitCount = 0;
ZipEntry zipEntry;
FileInputStream entryFile;
File[] files = dir.listFiles();
for (File file : files) {
zipEntry = new ZipEntry(basePath + file.getName());
if (file.isDirectory()) {
String path = basePath + file.getName() + "/";
zout.putNextEntry(new ZipEntry(path));
zipSubDirectory(path, file, zout);
zout.closeEntry();
} else {
if (currentSize >= MAX_ZIP_SIZE) {
zipSplitCount++;
zout.close();
zout = new ZipOutputStream(new FileOutputStream(file.getName().replace(".zip", ".zip." + zipSplitCount)));
currentSize = 0;
}
zout.putNextEntry(zipEntry);
FileInputStream fin = new FileInputStream(file);
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
currentSize += zipEntry.getCompressedSize();
}
}
}

Paste files inside a zip folder in java

I'm trying to figure out how to paste files into a folder inside .zip file. I'm using the code below just to add a file into zip, but not a specific folder within it. I'm not allowed to unzip this file. I have some basic text files to replace the files already existing with same name in the zip.
How to modify this method to choose a specific folder inside zip? Thanks!
public static void addFilesToExistingZip(File zipFile, File[] files) throws IOException {
File tempFile = File.createTempFile(zipFile.getName(), null);
tempFile.delete();
zipFile.renameTo(tempFile);
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) { // Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(name)); // Transfer bytes from the ZIP file to the output file
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
} // Close the streams
zin.close(); // Compress the files
for (int i = 0; i < files.length; i++) {
InputStream in = new FileInputStream(files[i]); // Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(files[i].getName())); // Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
} // Complete the entry
out.closeEntry();
in.close();
} // Complete the ZIP file
out.close();
tempFile.delete();
}

Adding (and overriding) files to compressed archive

Well, it is as simple as the title.
I tried for many hours to make a method that will take the archive file and a File[] (the files that will be added to the archive) and I only made it to the point that the method adds new files into the archive, but if a file with the same name of a file that I'm trying to add already exists, it throws me an error.
I tried searching for a solution but didn't find any.
Can you help me make a method that will take two parameters: File archive, File[] fileToAdd. That will add files to an archive and if needed will override existing files?
Thank you, TheRedCoder
Edit:
Here is my current code
public static void addFilesToZip(File zipFile, File[] files) throws IOException {
File tempFile = File.createTempFile(zipFile.getName(), null);
tempFile.delete();
boolean renameOk = zipFile.renameTo(tempFile);
if (!renameOk) {
throw new RuntimeException(
"could not rename the file " + zipFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
File file = null;
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
notInFiles = false;
file = f;
break;
}
}
if (notInFiles) {
out.putNextEntry(new ZipEntry(name));
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
} else {
/**
*
* I'm stuck here, what should i do here?
*
*/
}
entry = zin.getNextEntry();
}
zin.close();
for (int i = 0; i < files.length; i++) {
InputStream in = new FileInputStream(files[i]);
out.putNextEntry(new ZipEntry(files[i].getName()));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
in.close();
}
out.close();
tempFile.delete();
}

export/zip eclipse project via java program for Windows and MAC

I need to export a (java) eclipse project without using eclipse. I tried to copy all relevant files and pack them with a ZipOutputStream. So good so far, I can load this zip-file in Windows. But MAC users have the problem, that the file structure is not automaticaly detected and create files with names like "vorlage\src\de\tuberlin..." next to the src directory.
(example picture)
Is there a way to properly export an eclipse project with a java programm?
The reason is that I created programming exercises for a lecture and marked the solutions with special comments. During copying the files these comments and the solutions are left out.
One solution would be importing the zip-file in Windos and exporting again with the help of eclipse. But this costs a lot of time doing this for each exercise.
Although I cannot see any difference between the two zip-files, there seems to be something.
Here my code to copy the files:
public static void copyDir(File source, File target, ArrayList<String> exclude)
throws FileNotFoundException, IOException {
File[] files = source.listFiles();
File newFile = null;
target.mkdirs();
if (files != null) {
for (int i = 0; i < files.length; i++) {
newFile = new File(target.getAbsolutePath() + System.getProperty("file.separator") + files[i].getName());
if (files[i].isDirectory()) {
copyDir(files[i], newFile, exclude);
}
else if ( !exclude.contains(files[i].getName()) ) {
copyFile(files[i], newFile);
}
}
}
}
public static void copyFile(File file, File target) throws FileNotFoundException, IOException {
if (file.getName().endsWith(".java")) {
copyJavaFile(file, target);
return;
}
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target, true));
int bytes = 0;
while ((bytes = in.read()) != -1) {
out.write(bytes);
}
in.close();
out.close();
}
private static void copyJavaFile(File file, File target) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(target);
boolean stopped = false;
String line = null;
while ( (line = in.readLine() ) != null) {
stopped |= line.contains("IF EXCLUDE");
if (!stopped && !line.contains("ENDIF"))
out.println(line);
stopped &= !line.contains("ELSE");
}
in.close();
out.close();
}
I copy the following (sub-)directories/files:
.settings
src
.classpath
.project
I create the zip-file with:
public Zip(final File projDir, final File outFile) {
ZipOutputStream output = null;
try {
output = new ZipOutputStream(
new BufferedOutputStream(
new FileOutputStream(outFile)));
for (File file : projDir.listFiles()) {
writeFiles(file, output, "");
}
output.finish();
} catch (IOException ex) {
System.err.println("IO Error: " + ex.getMessage());
} finally {
try {output.close();} catch (IOException ex) {}
}
}
private void writeFiles(File f, ZipOutputStream output, String dir) throws IOException {
if (f.isDirectory()) {
// recursively write files in directory
for (File file : f.listFiles()) {
writeFiles(file, output, dir + f.getName() + File.separator);
}
} else {
// write this file to archive
FileInputStream fis = new FileInputStream(f);
ZipEntry entry = new ZipEntry(dir + f.getName());
entry.setTime(f.lastModified());
output.putNextEntry(entry);
copy(fis, output);
output.closeEntry();
fis.close();
}
}
private void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int bytes;
while ((bytes = is.read(buffer)) > 0) {
os.write(buffer, 0, bytes);
}
}
It is a problem of the path separator. Using "/" instead of "File.separator" solves the problem.
In the example above the for-loop in the method writeFiles(...) must be:
for (File file : f.listFiles()) {
writeFiles(file, output, dir + f.getName() + "/");
}
See also this answer.

Java - How to move a file into a zip file?

That's it. I have a text file, and I need to move it to a (existing) Zip File in a given directory.
File file = new File("C:\\afolder\\test.txt");
File dir = new File(directoryToGo+"existingzipfile.zip");
boolean success = file.renameTo(new File(dir, file.getName()));
But it does not work. Is there a way to move a file into a existing Zip File?
Thank you.
Hmm you could use something like:
public static void addFilesToExistingZip(File zipFile, File[] files) throws IOException {
// get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null);
// delete it, otherwise you cannot rename your existing zip to it.
tempFile.delete();
boolean renameOk = zipFile.renameTo(tempFile);
if (!renameOk) {
throw new RuntimeException(
"could not rename the file " + zipFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) { // Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(name)); // Transfer bytes from the ZIP file to the output file
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
} // Close the streams
zin.close(); // Compress the files
for (int i = 0; i < files.length; i++) {
InputStream in = new FileInputStream(files[i]); // Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(files[i].getName())); // Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
} // Complete the entry
out.closeEntry();
in.close();
} // Complete the ZIP file
out.close();
tempFile.delete();
}
Reference:
http://www.dzone.com/snippets/adding-files-existing-jar-file
You'll need to build a new zip file:
Open the existing zip file for reading
Open a new zip file for writing
Copy all the entries from the old zip file to the new one, ignoring an entry corresponding to your extra file, if there is one
Add your extra file
Close both the input and the output files
Delete the old zip file
Rename the new zip file to the old one's name
Starting with Java 7 you have a zip filesystem provider which allows you to write this code:
final Path src = Paths.get("c:\\afolder\\test.txt");
final String filename = src.getFileName().toString();
final Path zip = Paths.get(directoryToGo, "existingzipfile.zip");
final URI uri = URI.create("jar:" + zip.toUri());
final Map<String, ?> env = Collections.emptyMap();
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, env);
) {
Files.move(src, zipfs.getPath("/" + filename),
StandardCopyOption.REPLACE_EXISTING);
}
You can do like this, here uploadPath+fileName is filename with its path:
String FileName="Urzip file name. zip";
FileOutputStream outputStream = new FileOutputStream(uploadPath+fileName);
ZipOutputStream zipFile = new ZipOutputStream(outputStream);
byte[] buffer = new byte[1024];
// Then, here I have list of pdf files in a LIST:
// continuation ...
for (int i = 0; i < filename.size(); i++) {
String file = filename.get(i);
FileInputStream input = new FileInputStream(uploadPath+file);
ZipEntry entry = new ZipEntry(file);
zipFile.putNextEntry(entry);
int len;
while ((len = input.read(buffer)) > 0) {
zipFile.write(buffer, 0, len);
}
zipFile.closeEntry();
input.close();
}
// Next, here "downFile" is the other file which you have to add in your existing zip:
// continuation ...
FileInputStream input = new FileInputStream(uploadPath+downFile);
ZipEntry e = new ZipEntry(downFile);
zipFile.putNextEntry(e);
int len;
while ((len = input.read(buffer)) > 0) {
zipFile.write(buffer, 0, len);
}
zipFile.closeEntry();
input.close();
zipFile.close();
Adding the class to move the file to inside jar/zip folder based on accepted answer.
The accepted answer didn't hold full executable code ,So i have added the class which helps to move/copy the file to jar/zip
package ZipReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipWrite {
public static void main(String args[]) throws IOException
{
File file=new File("F:/MyProjects/New folder/mysql-connector-java-5.1.18-bin.jar");
File filetoPush=new File("F:/MyProjects/New folder/BestResponseTimeBalanceStrategy.class");
File[] files=new File[1];
files[0]=filetoPush;
addFilesToExistingZip(file,files);
}
public static void addFilesToExistingZip(File zipFile, File[] files)
throws IOException {
// get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null);
// delete it, otherwise you cannot rename your existing zip to it.
tempFile.delete();
boolean renameOk = zipFile.renameTo(tempFile);
if (!renameOk) {
throw new RuntimeException("could not rename the file "
+ zipFile.getAbsolutePath() + " to "
+ tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
System.out.println(name);
notInFiles = false;
break;
}
}
if (notInFiles) {
System.out.println("adding");
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(name)); // Transfer bytes from the
// ZIP file to the
// output file
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
} // Close the streams
zin.close(); // Compress the files
for (int i = 0; i < files.length; i++) {
FileInputStream in = new FileInputStream(files[i]);
// Add ZIP entry to output stream.
System.out.println("files[i].getName()-->"+files[i].getName());
out.putNextEntry(new ZipEntry("com/mysql/jdbc/util/"+files[i].getName()));
// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the ZIP file
out.close();
tempFile.delete();
}
}

Categories

Resources