ZipArchiveEntry charset-encoding error - java

I have to create a file zip with apache-commons-compress-1.x API.
I have used the following code:
File fileZip = new File("D:\\file.zip");
ZipEncoding zipEncoding = ZipEncodingHelper.getZipEncoding("UTF8");
ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(fileZip);
zipOut.setEncoding("UTF-8");
File entryFile = new File("D:\\attività.jpg");
String entryName = entryFile.getName();
entryName = new String(entryName.getBytes("UTF-8"), "UTF-8");
ZipArchiveEntry entry = new ZipArchiveEntry(entryName);
entry.setSize(entryFile.length());
FileInputStream fInputStream = new FileInputStream(entryFile);
zipOut.setUseLanguageEncodingFlag(true);
zipOut.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS);
zipOut.putArchiveEntry(entry);
zipOut.write(IOUtils.toByteArray(fInputStream));
zipOut.closeArchiveEntry();
zipOut.flush();
zipOut.close();
The zip entry file name has a encoding error. If I open the zipped file with zip manager built windows xp, the filename is attivit+á.jpg.
Help me, please.

Do
entryName = zipEncoding.encode("attivit\u00E0.jpg");

Related

How can I zip a directory with java.util.zip? [duplicate]

This question already has answers here:
How to zip the content of a directory in Java
(3 answers)
Closed 1 year ago.
I want to zip a folder into a zip file with java.util.zip tools.
I have already tried to read org.gradle.api.tasks.bundling.Zip in Gradle, but I cannot understand it at all.
Is there any code or opensource third-party tool that can zip a directory tree?
You can try using ZipOutputStream to create zip.
List<String> srcFiles = Arrays.asList("test1.txt", "test2.txt"); // List of all files
FileOutputStream fos = new FileOutputStream("multiCompressed.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
for (String srcFile : srcFiles) {
File fileToZip = new File(srcFile);
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
zipOut.close();
fos.close();
Since you have to zip a folder, you can read all the files inside folder and put inside list(Call method instead of hard coding file names in list ).
Below code I have written to read file from all folder and sub folder, You can make change in logic according to your requirements.
String path = "folderpath"
File dir = new File(path);
List<String> srcFiles = populateFilesList(dir);
private List<String> populateFilesList(File dir) throws IOException {
List filesListInDir = new ArrayList<String>();
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile())
{
filesListInDir.add(file.getAbsolutePath());
}
else
{
populateFilesList(file);
}
}
return filesListInDir;
}
Please try this and let me know if you face any issue.
What about use this lib Zeroturnaround Zip library
Then you will zip your folder just a one line:
ZipUtil.pack(new File("D:\sourceFolder\"), new File("D:\generatedZipFile.zip"));

how to upload file to Box subfolder using Java SDK

How to upload files to my Box Sub-Folder using either by subfolder name or ID
Example say I have 2 subfolders(subfolder1 and subfolder2) in my Box, How to upload files to subfolder2 using java sdk.
Can we upload using any new methods.
Successful in uploading files to Box root folder using the code below
BoxFolder bfolder = BoxFolder.getRootFolder(api);
FileInputStream stream= null;
filePath = "c:\\UploadFile.txt";
stream = new FileInputStream(filePath);
fileName = FilenameUtils.getBaseName(filePath.toString());
bfolder.uploadFile(stream, fileName);
You probably need to enumerate the folders till you find subfolder1, then create a new BoxFolder from that. Something like this (edit for compile errors):
BoxFolder bfolder = BoxFolder.getRootFolder(api);
Iterator<BoxFolder.Info> it = bfolder.getChildren().iterator();
for(BoxFolder.Info i : it){
if(i.getName().equals(subfolder1)){
BoxFolder folder = new BoxFolder(api, i.getID());
FileInputStream stream= null;
filePath = "c:\\UploadFile.txt";
stream = new FileInputStream(filePath);
fileName = FilenameUtils.getBaseName(filePath.toString());
folder.uploadFile(stream, fileName);
break;
}
}

Unzip file with special character through java.util.zip library

I have my zip file with several files inside it. When I run my unzip code:
public ArrayList<String> unzip(String zipFilePath, String destDirectory, String filename) throws IOException {
ArrayList<String> pathList = new ArrayList<String>();
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
// iterates over entries in the zip file
while (entry != null) {
// Original file name
// String filePath = destDirectory + File.separator + entry.getName();
int _ordPosition = entry.getName().indexOf("_ord");
if (_ordPosition<0)
throw new DatOrderException("Files inside zip file are not in correct format (please order them with _ordXX string)");
String ord = entry.getName().substring(_ordPosition,_ordPosition+6);
String filePath = destDirectory + File.separator + filename + ord + "."+ FilenameUtils.getExtension(entry.getName());
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
pathList.add(filePath);
extractFile(zipIn, filePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
return pathList;
}
if file inside archive contains special character like º I receive exception with Malformed message on row
ZipEntry entry = zipIn.getNextEntry();
Is it possible to rename this file or fix this error? Thanks
Try to read zip file with correct characters encoding - use ZipInputStream(java.io.InputStream, java.nio.charset.Charset) instead of ZipInputStream(java.io.InputStream)
As #Andrew Kolpakov suggested, with
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath),Charset.forName("IBM437"));
it seems to work

Cannot extract jar file in java application packaged for windows

My program was created in Netbeans 8.0.2. The program is supposed to create a (database) folder after installation and extract the contents of a (database) jar file from its library. The folder gets created quite okay, but the contents of the jar file do not get extracted.
How can I get the extraction of the jar file to work?
NB: When I run the program in Netbeans, everything goes well.
Sample Code:
String appHomeDir = new java.io.File(".").getCanonicalPath();
String destDir = appHomeDir + "/database";
File folder = new File(destDir);
if (!folder.exists()) {
folder.mkdir();
String current = new java.io.File(".").getCanonicalPath();
String jarFile = current + "\\app\\lib\\database.jar";
java.util.jar.JarFile jar = new java.util.jar.JarFile(jarFile);
java.util.Enumeration enumEntries = jar.entries();
while (enumEntries.hasMoreElements()) {
java.util.jar.JarEntry file = (java.util.jar.JarEntry) enumEntries.nextElement();
java.io.File f = new java.io.File(destDir + java.io.File.separator + file.getName());
if (file.isDirectory()) { // if its a directory, create it
f.mkdir();
continue;
}
java.io.InputStream is = jar.getInputStream(file); // get the input stream
java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
while (is.available() > 0) { // write contents of 'is' to 'fos'
fos.write(is.read());
}
fos.close();
is.close();
}
}
So the "database" directory gets created but the contents of "database.jar" do not get extracted.
Problem solved: I replaced "/app/lib/database.jar" with "/lib/database.jar"

Add an entry to a tar file without overwriting its existing contents

I need to add a config file to an existing tar file. I am using apache.commons.compress library. The following code snippet adds the entry correctly but overwrites the existing entries of the tar file.
public static void injectFileToTar () throws IOException, ArchiveException {
String agentSourceFilePath = "C:\\Work\\tar.gz\\";
String fileToBeAdded = "activeSensor.cfg";
String unzippedFileName = "sample.tar";
File f2 = new File(agentSourceFilePath+unzippedFileName); // Refers to the .tar file
File f3 = new File(agentSourceFilePath+fileToBeAdded); // The new entry to be added to the .tar file
// Injecting an entry in the tar
OutputStream tarOut = new FileOutputStream(f2);
TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", tarOut);
TarArchiveEntry entry = new TarArchiveEntry(fileToBeAdded);
entry.setMode(0100000);
entry.setSize(f3.length());
aos.putArchiveEntry(entry);
FileInputStream fis = new FileInputStream(f3);
IOUtils.copy(fis, aos);
fis.close();
aos.closeArchiveEntry();
aos.finish();
aos.close();
tarOut.close();
}
On checking the tar, only "activeSensor.cfg" file is found and the initial content of the tar is found missing. Is the "mode" not set correctly ?
The problem is that the TarArchiveOutputStream does not automatically read in the existing archive, which is something that you'd need to do. Something along the lines of:
CompressorStreamFactory csf = new CompressorStreamFactory();
ArchiveStreamFactory asf = new ArchiveStreamFactory();
String tarFilename = "test.tgz";
String toAddFilename = "activeSensor.cfg";
File toAddFile = new File(toAddFilename);
File tempFile = File.createTempFile("updateTar", "tgz");
File tarFile = new File(tarFilename);
FileInputStream fis = new FileInputStream(tarFile);
CompressorInputStream cis = csf.createCompressorInputStream(CompressorStreamFactory.GZIP, fis);
ArchiveInputStream ais = asf.createArchiveInputStream(ArchiveStreamFactory.TAR, cis);
FileOutputStream fos = new FileOutputStream(tempFile);
CompressorOutputStream cos = csf.createCompressorOutputStream(CompressorStreamFactory.GZIP, fos);
ArchiveOutputStream aos = asf.createArchiveOutputStream(ArchiveStreamFactory.TAR, cos);
// copy the existing entries
ArchiveEntry nextEntry;
while ((nextEntry = ais.getNextEntry()) != null) {
aos.putArchiveEntry(nextEntry);
IOUtils.copy(ais, aos, (int)nextEntry.getSize());
aos.closeArchiveEntry();
}
// create the new entry
TarArchiveEntry entry = new TarArchiveEntry(toAddFilename);
entry.setSize(toAddFile.length());
aos.putArchiveEntry(entry);
IOUtils.copy(new FileInputStream(toAddFile), aos, (int)toAddFile.length());
aos.closeArchiveEntry();
aos.finish();
ais.close();
aos.close();
// copies the new file over the old
tarFile.delete();
tempFile.renameTo(tarFile);
A couple of notes:
This code does not include any exception handling (please add the appropriate try-catch-finally blocks)
This code does not handle files with a size over 2147483647 (Integer.MAX_VALUE) as it only reads file sizes to integer precision bytes (see the cast to int). However, that's not a problem as Apache Compress does not handle files over 2 GB anyway.
Try changing
OutputStream tarOut = new FileOutputStream(f2);
to
OutputStream tarOut = new FileOutputStream(f2, true); //Set append to true

Categories

Resources