I want to write a unit test to test creating .zip file from two .doc files. BU I take an error: Error creating zip file: java.io.FileNotFoundException: D:\file1.txt (The system cannot find the file specified)
My code is here:
#Test
public void testIsZipped() {
String actualValue1 = "D:/file1.txt";
String actualValue2 = "D:/file2.txt";
String zipFile = "D:/file.zip";
String[] srcFiles = { actualValue1, actualValue2 };
try {
// create byte buffer
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(fos);
for (int i = 0; i < srcFiles.length; i++) {
File srcFile = new File(srcFiles[i]);
FileInputStream fis = new FileInputStream(srcFile);
// begin writing a new ZIP entry, positions the stream to the
// start of the entry data
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
fis.close();
}
// close the ZipOutputStream
zos.close();
}
catch (IOException ioe) {
System.out.println("Error creating zip file: " + ioe);
}
String result = zos.toString();
assertEquals("D:/file.zip", result);
}
Can I get name of zip file from zos to test, How to understand to pass the test? Can anybody help me to solve this error? Thank you.
First, are your files created in a previous test method? If yes consider that junit tests do not execute in the order you defined your test methods, have a look at this:
How to run test methods in specific order in JUnit4?
Second, you could add a debugging line:
File srcFile = new File(srcFiles[i]);
System.out.append(srcFile+ ": " + srcFile.exists() + " " + srcFile.canRead());
After you solve the exception you will run into this problem, the test will fail:
String result = zos.toString();
assertEquals("D:/file.zip", result);
zos.toString() will return something like: "java.util.zip.ZipOutputStream#1ae369b7" which will not be equal to "D:/file.zip".
String zipFile = "D:/file.zip";
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
System.out.println(zos.toString());
Related
My app is a tender document system where each tender number has one or more pdf files attached.
application is done in java ee using struts and mysql.
in a database table the paths of each related pdf file for a tender number is stores.
I want to get all the pdf files and create a single ZIP file for each tender number so that user can download that zip file and have all the related documents in a single click.
I tried Google and found something called ZipOutputStream but i cannot understand how to use this in my application.
You're almost there... This is a small example of how to use ZipOutputStream... let's asume that you have a JAVA helper H that returns database records with pdf file paths (and related info):
FileOutputStream zipFile = new FileOutputStream(new File("xxx.zip"));
ZipOutputStream output = new ZipOutputStream(zipFile);
for (Record r : h.getPdfRecords()) {
ZipEntry zipEntry = new ZipEntry(r.getPdfName());
output.putNextEntry(zipEntry);
FileInputStream pdfFile = new FileInputStream(new File(r.getPath()));
IOUtils.copy(pdfFile, output); // this method belongs to apache IO Commons lib!
pdfFile.close();
output.closeEntry();
}
output.finish();
output.close();
Checkout this code, here you can easily create a zip file directory:
public class CreateZipFileDirectory {
public static void main(String args[])
{
try
{
String zipFile = "C:/FileIO/zipdemo.zip";
String sourceDirectory = "C:/examples";
//create byte buffer
byte[] buffer = new byte[1024];
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File dir = new File(sourceDirectory);
if(!dir.isDirectory())
{
System.out.println(sourceDirectory + " is not a directory");
}
else
{
File[] files = dir.listFiles();
for(int i=0; i < files.length ; i++)
{
System.out.println("Adding " + files[i].getName());
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
}
zout.close();
System.out.println("Zip file has been created!");
}
catch(IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
}
My task is to tar list of files and this tar should be kept in .gz file. I have succeeded in creating .tar file, but the next step like when creating .gz file I got an issue. After creating .gz file with a tar inside is converted into File format without any extension.
java code to generate .tar file
FileSystem fs = FileSystems.getDefault();
OutputStream tar_output = new FileOutputStream(fs.getPath(hardLink.toString(), tarFileName + ".tar")
.toFile());
ArchiveOutputStream my_tar_ball = new ArchiveStreamFactory().createArchiveOutputStream(
ArchiveStreamFactory.TAR, tar_output);
Path p = null;
TarArchiveEntry tar_file = null;
for (String list : certFileList) {
p = fs.getPath(hardLink.toString(), list);
tar_file = new TarArchiveEntry(p.getFileName().toString());
tar_file.setSize(p.toFile().length());
my_tar_ball.putArchiveEntry(tar_file);
IOUtils.copy(new FileInputStream(p.toFile()), my_tar_ball);
my_tar_ball.closeArchiveEntry();
}
call gzipIt function
gzipIt(hardLink.toString() + "/" + tarFileName + ".gz", hardLink.toString() + "/" + tarFileName + ".tar");
Java code to generate .gz file
public static void gzipIt(String outputDir, String sourceFile) {
byte[] buffer = new byte[1024];
try {
FileOutputStream fos = new FileOutputStream(new File(outputDir));
GZIPOutputStream gzos = new GZIPOutputStream(fos);
FileInputStream in = new FileInputStream(sourceFile);
int len;
while ((len = in.read(buffer)) > 0) {
gzos.write(buffer, 0, len);
}
in.close();
gzos.finish();
gzos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Could anyone help me in resolving the issue.
Regards
Sai
I am facing an unusal issue.I am building a tool which is scheduled to run every 5 mins.
It will pick up the zip files from a particular directory and extract files (depending on the file name) to a destination. I am using zipentry to get each filename in zip file and then extracting as required then I back them (zip files, once I finish all the files in a zip) to a particular directory and then delete the zip file. But sometimes (not always) the zip files do not get deleted. Since I am using fileutils.forcedelete(). I am getting an exception: unable to delete file. So I changed to the code to using fileutils.forcedeleteonexit() still some files remain in the source.
Here is a sample of my code:
sourceFile=new file(zipfile);
zipFile = new ZipFile(sourceFile);
zEnum = (Enumeration<ZipEntry>) zipFile.entries();
for (int a = 0; a < zipFile.size(); a++)
{
ZipEntry zE = zEnum.nextElement();
//Function uses zip4j for extracting. No streams used.
extract(String sourceZipFile, String fileNameToExtract, String outputFolder);
}
//I tried it with finally either
zipFile.close();
//Using fileutils to copy. No streams used.
copyFile(sourceFile, backup);
FileUtils.forceDeleteOnExit(sourceFile);
There are no streams used but I am getting a lock on files sometimes (not always).
What seems to be the bug here? Is it the zip4j extraction that is causing the problem or anything else? I am using zip4j 1.3.1.
I think your problem related with OS file buffers, that sometimes are not flushed when you are trying to delete file.
Did you try to use sourceFile.deleteOnExit() instead FileUtils.forceDeleteOnExit(sourceFile)?
Also you can try to check sourceFile.canWrite before deleting (may be it may helps)
You can also try to use FileInputStream() before deleting:
FileInputStream fi = new FileInputStream(sourceFile);
fi.getFD().sync();
Use apache-commons IO's FileDeleteStrategy. Something like:
FileDeleteStrategy.FORCE.delete(file);
Update:
It should be the way IO is being handled in your application. I have written simple code which copies a zip file to a temporary zip, deflates the temporary zip and after few seconds deletes it. Here you go:
public class ZipTest {
private static String dirPath = "/home/ubuntuuser/Desktop/";
public static void main(String[] args) throws Exception {
File myzip = new File(dirPath + "content.zip");
String tempFileStr = dirPath + "content_temp.zip";
File tempFile = new File(tempFileStr);
String unzipFolderStr = dirPath + "unzip";
copyUsingChannels(myzip, tempFile);
// copyUsingStreams(myzip, tempFile);
unZip(tempFileStr, unzipFolderStr);
Thread.sleep(3000);
tempFile.delete();
}
private static void copyUsingStreams(File myzip, File tempFile)
throws IOException, FileNotFoundException {
byte[] barray = new byte[1024];
if (!tempFile.exists())
{
tempFile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(tempFile);
FileInputStream fis = new FileInputStream(myzip);
int length = 0;
while ((length = fis.read(barray)) != -1)
{
fos.write(barray, 0, length);
}
fis.close();
fos.close();
}
public static void copyUsingChannels(final File srcFile, final File destFile) throws Exception
{
if (!destFile.exists())
{
destFile.createNewFile();
}
FileChannel source = new FileInputStream(srcFile).getChannel();
FileChannel destination = new FileOutputStream(destFile).getChannel();
source.transferTo(0, source.size(), destination);
source.close();
destination.close();
}
private static void unZip(String zipFile, String outputFolder) throws Exception {
byte[] buffer = new byte[1024];
File folder = new File(outputFolder);
if (!folder.exists()) {
folder.mkdir();
}
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
System.out.println("file unzip : " + newFile.getAbsoluteFile());
new File(newFile.getParent()).mkdirs();
if (ze.isDirectory())
{
newFile.mkdir();
ze = zis.getNextEntry();
continue;
}
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
}
}
I have a silly problem i haven't been able to figure out. Can anyone help me?
My Code is as:
String zipname = "C:/1100.zip";
String output = "C:/1100";
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
ZipFile zipFile = new ZipFile(zipname);
Enumeration<?> enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
System.out.println("Unzipping: " + zipEntry.getName());
bis = new BufferedInputStream(zipFile.getInputStream(zipEntry));
int size;
byte[] buffer = new byte[2048];
It doesn't create a folder but debugging shows all the contents being generated.
In Order to create a folder i used the code
if(!output.exists()){ output.mkdir();} // here i get an error saying filenotfoundexception
bos = new BufferedOutputStream(new FileOutputStream(new File(outPut)));
while ((size = bis.read(buffer)) != -1) {
bos.write(buffer, 0, size);
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
bos.flush();
bos.close();
bis.close();
}
My zip file contains images: a.jpg b.jpg... and in the same hierarchy, I have abc.xml.
I need to extract the content as is in the zip file.
Any helps here.
There are a few problems with your code: Where is outPut declared? output is not a file but a string, so exists() and mkdir() do not exist. Start by declaring output like:
File output = new File("C:/1100");
Furthermore, outPut (with big P) is not declared. It be something like output + File.seprator + zipEntry.getName().
bos = new BufferedOutputStream(new FileOutputStream(output + File.seprator + zipEntry.getName()));
Note that you don't need to pass a File to FileOutputStream, as constructors show in the documentation.
At this point, your code should work if your Zip file does not contain directory. However, when opening the output stream, if zipEntry.getName() has a directory component (for instance somedir/filename.txt), opening the stream will result in a FileNotFoundException, as the parent directory of the file you try to create does not exist. If you want to be able to handle such zip files, you will find your answer in: How to unzip files recursively in Java?
For example, I want to zip a file stored in /Users/me/Desktop/image.jpg
I made this method:
public static Boolean generateZipFile(ArrayList<String> sourcesFilenames, String destinationDir, String zipFilename){
// Create a buffer for reading the files
byte[] buf = new byte[1024];
try {
// VER SI HAY QUE CREAR EL ROOT PATH
boolean result = (new File(destinationDir)).mkdirs();
String zipFullFilename = destinationDir + "/" + zipFilename ;
System.out.println(result);
// Create the ZIP file
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFullFilename));
// Compress the files
for (String filename: sourcesFilenames) {
FileInputStream in = new FileInputStream(filename);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(filename));
// 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();
return true;
} catch (IOException e) {
return false;
}
}
But when I extract the file, the unzipped files have the full path.
I don't want the full path of each file in the zip i only want the filename.
How can I made this?
Here:
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(filename));
You're creating the entry for that file using the whole path. If you just use the name ( without the path ) you'll have what you need:
// Add ZIP entry to output stream.
File file = new File(filename); //"Users/you/image.jpg"
out.putNextEntry(new ZipEntry(file.getName())); //"image.jpg"
You're finding your source data using the relative path to the file, then setting the Entry to the same thing. Instead you should turn the source into a File object, and then use
putNextEntry(new ZipEntry(sourceFile.getName()))
that'll give you just the final part of the path (ie, the actual file name)
Do as Jason said, or if you want to keep your method signature, do it like this:
out.putNextEntry(new ZipEntry(new File(filename).getName()));
or, using FileNameUtils.getName from apache commons/io:
out.putNextEntry(new ZipEntry(FileNameUtils.getName(filename)));
You could probably get away with accessing source files via new FileInputStream(new File(sourceFilePath, sourceFileName)).
// easy way of zip a file
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample{
public static void main(String[] args) throws Exception {
// input file
FileInputStream in = new FileInputStream("F:/ZipCreateExample.txt");;
// out put file
ZipOutputStream out =new ZipOutputStream(new FileOutputStrea("F:/tmp.zip"));
// name of file in zip folder
out.putNextEntry(new ZipEntry("zippedfile.txt"));
byte[] b = new byte[1024];
int count;
// writing files to new zippedtxt file
while ((count = in.read(b)) > 0) {
System.out.println();
out.write(b, 0, count);
}
out.close();
in.close();
}
}
try {
String zipFile = "/locations/data.zip";
String srcFolder = "/locations";
File folder = new File(srcFolder);
String[] sourceFiles = folder.list();
//create byte buffer
byte[] buffer = new byte[1024];
/*
* To create a zip file, use
*
* ZipOutputStream(OutputStream out) constructor of ZipOutputStream
* class.
*/
//create object of FileOutputStream
FileOutputStream fout = new FileOutputStream(zipFile);
//create object of ZipOutputStream from FileOutputStream
ZipOutputStream zout = new ZipOutputStream(fout);
for (int i = 0; i < sourceFiles.length; i++) {
if (sourceFiles[i].equalsIgnoreCase("file.jpg") || sourceFiles[i].equalsIgnoreCase("file1.jpg")) {
sourceFiles[i] = srcFolder + fs + sourceFiles[i];
System.out.println("Adding " + sourceFiles[i]);
//create object of FileInputStream for source file
FileInputStream fin = new FileInputStream(sourceFiles[i]);
/*
* To begin writing ZipEntry in the zip file, use
*
* void putNextEntry(ZipEntry entry) method of
* ZipOutputStream class.
*
* This method begins writing a new Zip entry to the zip
* file and positions the stream to the start of the entry
* data.
*/
zout.putNextEntry(new ZipEntry(sourceFiles[i].substring(sourceFiles[i].lastIndexOf("/") + 1)));
/*
* After creating entry in the zip file, actually write the
* file.
*/
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
/*
* After writing the file to ZipOutputStream, use
*
* void closeEntry() method of ZipOutputStream class to
* close the current entry and position the stream to write
* the next entry.
*/
zout.closeEntry();
//close the InputStream
fin.close();
}
}
//close the ZipOutputStream
zout.close();
System.out.println("Zip file has been created!");
} catch (IOException ioe) {
System.out.println("IOException :" + ioe);
}
If you zip two files of the same name but with different paths you will run into duplicate file entry errors, though.