I am trying to zip two folder with each having some text file. Now I want that 2 folders should zip as one folder with their respective files.
I tried to code, but there is some issue with the zip.
The Zip contains multiple folders.
Here is the code:
package com.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFolders
{
public static void main(String[] args) throws IOException
{
List<String> listOfDir = new ArrayList<String>();
String dirpath1 = "/home/administrator/Documents/ZipTest/folder1";
String dirpath2 = "/home/administrator/Documents/ZipTest/folder2";
String ZipName = "/home/administrator/Documents/ZipTest/output.zip";
listOfDir.add(dirpath1);
listOfDir.add(dirpath2);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ZipName));
zipDirectories(listOfDir,zos);
zos.close();
System.out.println("Zip Created Successfully");
}
private static void zipDirectories(List<String> listOfDir, ZipOutputStream zos) {
for(String dirPath:listOfDir){
try {
zipdirectory(dirPath, zos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void zipdirectory(String dirpath, ZipOutputStream zos) throws IOException
{
File f = new File(dirpath);
String[] flist = f.list();
for(int i=0; i<flist.length; i++)
{
File ff = new File(f,flist[i]);
if(ff.isDirectory())
{
zipdirectory(ff.getPath(),zos);
continue;
}
String filepath = ff.getPath();
ZipEntry entries = new ZipEntry(filepath);
zos.putNextEntry(entries);
FileInputStream fis = new FileInputStream(ff);
int buffersize = 1024;
byte[] buffer = new byte[buffersize];
int count;
while((count = fis.read(buffer)) != -1)
{
zos.write(buffer,0,count);
}
fis.close();
}
}
}
But the output I am getting is not as expected I am getting folder 1 & folder 2
like
output.zip//home/administrator/Documents/ZipTest/ then here we are having our folder1 & folder2.
My expected output was :- inside the zip only the two folders should exist with there files.
Your zipdirectory method is used recursive here:
if(ff.isDirectory())
{
zipdirectory(ff.getPath(),zos);
continue;
}
That is creating all the folders you see.
You need to distiquish between the path of each file/dir and the path of the zip entry:
private static void zipDirectories(List<String> listOfDir, ZipOutputStream zos) {
for(String dirPath:listOfDir){
try {
File dir = new File(dirPath);
zipdirectory(dir, dir.getName(), zos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void zipdirectory(File dir, String dirpath,
ZipOutputStream zos) throws IOException
{
String[] flist = dir.list();
for(int i=0; i<flist.length; i++)
{
String fn = flist[i];
String fp = dirpath == null || dirpath.isEmpty()
? fn : dirpath + "/" + fn;
File ff = new File(dir, fn);
if(ff.isDirectory())
{
zipdirectory(ff, fp,zos);
continue;
}
ZipEntry entries = new ZipEntry(fp);
zos.putNextEntry(entries);
FileInputStream fis = new FileInputStream(ff);
int buffersize = 1024;
byte[] buffer = new byte[buffersize];
int count;
while((count = fis.read(buffer)) != -1)
{
zos.write(buffer,0,count);
}
fis.close();
}
}
Copy , Paste the Code and Run it for the result :-
package com.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFolders
{
public static void main(String[] args) throws IOException
{
List<String> listOfDir = new ArrayList<String>();
String dirpath1 = "/home/administrator/Documents/ZipTest/folder1";
String dirpath2 = "/home/administrator/Documents/ZipTest/folder2";
String ZipName = "/home/administrator/Documents/ZipTest/output.zip";
listOfDir.add(dirpath1);
listOfDir.add(dirpath2);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ZipName));
zipDirectories(listOfDir,zos);
zos.close();
System.out.println("Zip Created Successfully");
}
private static void zipDirectories(List<String> listOfDir, ZipOutputStream zos) {
for(String dirPath:listOfDir){
try {
zipdirectory(dirPath, zos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void zipdirectory(String dirpath, ZipOutputStream zos) throws IOException
{
File f = new File(dirpath);
String[] flist = f.list();
for(int i=0; i<flist.length; i++)
{
File ff = new File(f,flist[i]);
if(ff.isDirectory())
{
zipdirectory(ff.getPath(),zos);
continue;
}
String fileName = ff.getPath().substring(ff.getPath().lastIndexOf('/'));
String folder = dirpath.substring(dirpath.lastIndexOf('/')+1);
ZipEntry entries = new ZipEntry(folder+fileName);
zos.putNextEntry(entries);
FileInputStream fis = new FileInputStream(ff);
int buffersize = 1024;
byte[] buffer = new byte[buffersize];
int count;
while((count = fis.read(buffer)) != -1)
{
zos.write(buffer,0,count);
}
fis.close();
}
}
}
Related
I have a piece of code that iterates over all the files in a directory.
But I am stuck now at reading the content of the file into a String object.
public String filemethod(){
if (path.isDirectory()) {
files = path.list();
String[] ss;
for (int i = 0; i < files.length; i++) {
ss = files[i].split("\\.");
if (files[i].endsWith("txt"))
System.out.println(files[i]);
}
}
return String.valueOf(files);
}
Faced with a similar problem and wrote a code a while back. This will read the content of all files of a directory.
May require adjustments based on your file directories but its tried and tested code.Hope this helps :)
package FileHandling;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class BufferedInputStreamExample {
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
public void readFile(File folder) {
ArrayList<File> myFiles = listFilesForFolder(folder);
for (File f : myFiles) {
String path = f.getAbsolutePath();
//Path of the file(Optional-You can know which file's content is being printed)
System.out.println(path);
File infile = new File(path);
try {
fis = new FileInputStream(infile);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while (dis.available() != 0) {
String line = dis.readLine();
System.out.println(line);
}
} catch (IOException e) {
} finally {
try {
fis.close();
bis.close();
dis.close();
} catch (Exception ex) {
}
}
}
}
public ArrayList<File> listFilesForFolder(final File folder){
ArrayList<File> myFiles = new ArrayList<File>();
for (File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
myFiles.addAll(listFilesForFolder(fileEntry));
} else {
myFiles.add(fileEntry);
}
}
return myFiles;
}
}
Main method
package FileHandling;
import java.io.File;
public class Main {
public static void main(String args[]) {
//Your directory here
final File folder = new File("C:\\Users\\IB\\Documents\\NetBeansProjects\\JavaIO\\files");
BufferedInputStreamExample bse = new BufferedInputStreamExample();
bse.readFile(folder);
}
}
I would use following code:
public static Collection<File> allFilesInDirectory(File root) {
Set<File> retval = new HashSet<>();
Stack<File> todo = new Stack<>();
todo.push(root);
while (!todo.isEmpty()) {
File tmp = todo.pop();
if (tmp.isDirectory()) {
for (File child : tmp.listFiles())
todo.push(child);
} else {
if (isRelevantFile(tmp))
retval.add(tmp);
}
}
return retval;
}
All you need then is a method that defines what files are relevant for your usecase (for instance txt)
public static boolean isRelevantFile(File tmp) {
// get the extension
String ext = tmp.getName().contains(".") ? tmp.getName().substring(tmp.getName().lastIndexOf('.') + 1) : "";
return ext.equalsIgnoreCase("txt");
}
Once you have all the files, you can easily get all the text with a little hack in Scanner
public static String allText(File f){
// \\z is a virtual delimiter that marks end of file/string
return new Scanner(f).useDelimiter("\\z").next();
}
So now, using these methods you can easily extract all the text from an entire directory.
public static void main(String[] args){
File rootDir = new File(System.getProperty("user.home"));
String tmp = "";
for(File f : allFilesInDirectory(rootDir)){
tmp += allText(f);
}
System.out.println(tmp);
}
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ReadDataFromFiles {
static final File DIRECTORY = new File("C:\\myDirectory");
public static void main(String[] args) throws IOException {
StringBuilder sb = new StringBuilder();
//append content of each file to sb
for(File f : getTextFiles(DIRECTORY)){
sb.append(readFile(f)).append("\n");
}
System.out.println(sb.toString());
}
// get all txt files from the directory
static File[] getTextFiles(File dir){
FilenameFilter textFilter = (File f, String name) -> name.toLowerCase().endsWith(".txt");
return dir.listFiles(textFilter);
}
// read the content of a file to string
static String readFile(File file) throws IOException{
return new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())), StandardCharsets.UTF_8);
}
}
I am new to java and I am having trouble specifying where to save the folder after I zipped it. It always go to the project workspace that I am creating. I want it to be saved in the path
"C:\\Users\\win8.1\\Desktop\\AES"
Here is the code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipUtils
{
private List<String> fileList;
private static final String OUTPUT_ZIP_FILE = "Folder.zip";
private static final String SOURCE_FOLDER = "C:\\Users\\win8.1\\Desktop\\AES\\SAMPLEPATH"; // SourceFolder path
public ZipUtils()
{
fileList = new ArrayList<String>();
}
public static void main(String[] args)
{
ZipUtils appZip = new ZipUtils();
appZip.generateFileList(new File(SOURCE_FOLDER));
appZip.zipIt(OUTPUT_ZIP_FILE);
}
public void zipIt(String zipFile)
{
byte[] buffer = new byte[1024];
String source = "";
FileOutputStream fos = null;
ZipOutputStream zos = null;
try
{
try
{
source = SOURCE_FOLDER.substring(SOURCE_FOLDER.lastIndexOf("\\") + 1, SOURCE_FOLDER.length());
}
catch (Exception e)
{
source = SOURCE_FOLDER;
}
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(fos);
System.out.println("Output to Zip : " + zipFile);
FileInputStream in = null;
for (String file : this.fileList)
{
System.out.println("File Added : " + file);
ZipEntry ze = new ZipEntry(source + File.separator + file);
zos.putNextEntry(ze);
try
{
in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
int len;
while ((len = in.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
}
finally
{
in.close();
}
}
zos.closeEntry();
System.out.println("Folder successfully compressed");
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
try
{
zos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public void generateFileList(File node)
{
// add file only
if (node.isFile())
{
fileList.add(generateZipEntry(node.toString()));
}
if (node.isDirectory())
{
String[] subNote = node.list();
for (String filename : subNote)
{
generateFileList(new File(node, filename));
}
}
}
private String generateZipEntry(String file)
{
return file.substring(SOURCE_FOLDER.length() + 1, file.length());
}
}
I got the code here. Thank you in advance!
There is no problem. Just write
private static final String OUTPUT_ZIP_FILE = "C:\\Users\\win8.1\\Desktop\\AES\\Folder.zip";
private static final String SOURCE_FOLDER = "C:\\Users\\win8.1\\Desktop\\AES\\SAMPLEPATH";
So i created a zip and created a new sub folder in the zip file by creating a zip entry that ends in "\". How would i write to the subfolder?
My problem is i have a putnextEntry call on my ZipOutputStream in a for loop so after the folder gets created i then jump into a for loop where the different zip files are written. But they are written at the same level as the subdir within the zip.
What i think is happening is because i use putNextEntry with the first actual zip(not dir) entry it is closing the subfolder and writing to the root of the zip. Any ideas?
Code below
private int endprocess() {
try {
zipFolder(ripPath, zipOutputPath, "rips");
//zipFolder(destPDFfiles, zipOutputPath, "pdfs");
this.returnCode = 0;
//log.debug ( "Accumulator count: " + acount);
log.debug("Equivest count: " + ecount);
//log.debug ( "Assoc count: " + scount);
processEndOfEnvelope();
} catch (Exception reportException) {
log.logError("Caught exception in creating.");
reportException.printStackTrace();
this.returnCode = 15;
}
return (this.returnCode);
}
public static void zipFolder(String srcFolder, String dest, String outputFolder){
try{
ZipOutputStream zos = null;
FileOutputStream fos = null;
fos = new FileOutputStream(dest + "\\newzip.zip");
zos = new ZipOutputStream(fos);
addFolderToZip(srcFolder, zos, outputFolder);
zos.flush();
zos.close();
}catch(IOException e){
log.logError("**********************");
log.logError("IO Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
private static void addFileToZip(String srcFile, ZipOutputStream zos, String outputFolder){
try {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(srcFile, zos, outputFolder);
} else {
byte[] buffer = new byte[1024];
int length;
FileInputStream fis = new FileInputStream(srcFile);
ZipEntry ze = new ZipEntry("C:\\AWDAAV\\zip\\newzip.zip\\" + outputFolder + "\\" + folder.getName());
zos.putNextEntry(ze);
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
}catch(Exception e){
log.logError("**********************");
log.logError("Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
private static void addFolderToZip(String srcFolder, ZipOutputStream zos, String outputFolder){
try{
File folder = new File(srcFolder);
zos.putNextEntry(new ZipEntry(outputFolder + "\\"));
for(String fileName : folder.list()){
addFileToZip(srcFolder + "\\" + fileName, zos, outputFolder);
}
}catch(Exception e){
log.logError("**********************");
log.logError("Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
I had a look at your code and i think the ZIP API works just as you think.
Only you had some logic errors with the path names.
You need to convert the path names from the local names to the relative locations in the zip file.
Maybe you got confused somewhere in that area.
Here is my suggestion:
File: org/example/Main.java
package org.example;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException {
MyZip myZip = new MyZip();
Path sourcePath = Paths.get("C:/Users/David/Desktop/a");
Path targetPath = Paths.get("C:/Users/David/Desktop/zip/out.zip");
Path zipPath = Paths.get("tadaa");
myZip.zipFolder(sourcePath, targetPath.toFile(), zipPath);
}
}
Update: Explanation of variables in main method
The sourcePath is a directory which content you want to include in the zip archive.
The targetPath is the output path of the zip file. For example the new zip file will be created at exactly that location.
The zipPath is the subdirectory within the zip directory where your content from sourcePath will be placed. This variable may also be set to null. If it is null the sourcePath will be put in the root of the new zip archive.
File: org/example/MyZip.java
package org.example;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class MyZip {
public void zipFolder(Path base, File dest, Path zipFolder) throws IOException {
try (FileOutputStream fos = new FileOutputStream(dest);
ZipOutputStream zos = new ZipOutputStream(fos)) {
addFolderToZip(base.getParent(), base, zos, zipFolder);
}
}
private void addFolderToZip(Path base, Path currentFolder, ZipOutputStream zos, Path zipFolder) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentFolder)) {
for(Path path : stream) {
Path relativePath = base != null ? base.relativize(path) : path;
Path pathInZip = zipFolder != null ? zipFolder.resolve(relativePath) : relativePath;
if(path.toFile().isDirectory()) {
zos.putNextEntry(new ZipEntry(pathInZip.toString() + "/"));
// recurse to sub directories
addFolderToZip(base, path, zos, zipFolder);
} else {
addFileToZip(path, pathInZip, zos);
}
}
}
}
private void addFileToZip(Path sourcePath, Path pathInZip, ZipOutputStream zos) throws IOException {
byte[] buffer = new byte[1024];
int length;
try (FileInputStream fis = new FileInputStream(sourcePath.toFile())) {
ZipEntry ze = new ZipEntry(pathInZip.toString());
zos.putNextEntry(ze);
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
}
}
ZipEntry.setLevel(filepath[in your case, \folder]);
I'm writing a java program that will extract zip file and rename the file inside it to the zip file name. For example: the zip file name is zip.zip and the file inside it is content.txt. Here i want to extract the zip file and the content.txt has to be renamed to zip.txt. I'm trying the below program.
And here there would be only one file in the zip file
Zip.Java
import java.io.BufferedOutputStream;
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;
public class zip {
private static final int BUFFER_SIZE = 4096;
public void unzip(String zipFilePath, String destDirectory) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
extractFile(zipIn, filePath, zipFilePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
private void extractFile(ZipInputStream zipIn, String filePath, String zipFilePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
File oldName = new File(filePath);
System.out.println(oldName);
String str = zipFilePath.substring(zipFilePath.lastIndexOf("\\") + 1, zipFilePath.lastIndexOf("."));
System.out.println(str);
File zipPath = new File(zipFilePath);
System.out.println(zipPath.getParent());
File newName = new File(zipPath.getParent() + "\\" + str);
System.out.println(newName);
if (oldName.renameTo(newName)) {
System.out.println("Renamed");
} else {
System.out.println("Not Renamed");
}
bos.close();
}
}
UnZip.Java
public class UnZip {
public static void main(String[] args) {
String zipFilePath = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip\\New Companies Ordinance (Vol Two)_xml.zip";
String destDirectory = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip";
zip unzipper = new zip();
try {
unzipper.unzip(zipFilePath, destDirectory);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Here i was able to extract the file but unable to rename it. please let me knw where am i going wrong and how to fix it.
Thanks
Close your BufferedOutputStream directly after the last write instruction (after the while loop). Only then will it release its lock on the file and will you be able to rename the file.
See: http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#close()
package com.otp.util;
import java.io.FileWriter; import java.io.IOException; import
java.text.SimpleDateFormat; import java.util.Date;
import com.otp.servlets.MessageServlet;
public class CDRWriter {
public FileWriter fileWriter = null;
static int lineCounter = 0;
static String fileName = null;
public void writeCDR(String cdrData) throws IOException {
if(lineCounter == 0){
fileName = createFile();
}else if(lineCounter>500){
String temp=fileName;
fileName = createFile();
lineCounter=0;
Runtime rt = Runtime.getRuntime();
String zipCmd="7z a "+"\""+MessageServlet.filePath+temp+".7z"+"\""+" "+"\""+MessageServlet.filePath+temp+"\"";
System.out.println("zipCmd = "+zipCmd);
rt.exec(zipCmd);
//rt.exec("del "+MessageServlet.filePath+temp);
}
System.out.println("cdr data = "+cdrData);
try {
if(lineCounter == 0){
fileWriter = new FileWriter(MessageServlet.filePath+fileName);
}else{
fileWriter = new FileWriter(MessageServlet.filePath+fileName,true);
}
System.out.println("cdr after if else condition ="+cdrData);
fileWriter.write(cdrData.toString());
System.out.println("cdr after write method ="+cdrData);
fileWriter.write("\r\n");
fileWriter.flush();
//fileWriter.close();
lineCounter++;
System.out.println("CDRWriter : lineCounter = "+lineCounter); } catch (IOException e) {
e.printStackTrace();
}
}// end of WriterCDR method
public String createFile() throws IOException {
SimpleDateFormat sdf = new
SimpleDateFormat("dd-MM-yyyy-HH-mm-ss");
String fileName ="GSMS_CDR_"+ sdf.format(new Date())+".txt" ;
return fileName;
}// end of the createFile method
}// end of CDRWriter class
I would do something like that:
import java.io.*;
import SevenZip.Compression.LZMA.*;
public class Create7Zip
{
public static void main(String[] args) throws Exception
{
// file to compress
File inputToCompress = new File(args[0]);
BufferedInputStream inputStream = new BufferedInputStream(new java.io.FileInputStream(inputToCompress));
// archive
File compressedOutput = new File(args[1] + ".7z");
BufferedOutputStream outputStream = new BufferedOutputStream(new java.io.FileOutputStream(compressedOutput));
Encoder encoder = new Encoder();
encoder.SetAlgorithm(2);
encoder.SetDictionarySize(8388608);
encoder.SetNumFastBytes(128);
encoder.SetMatchFinder(1);
encoder.SetLcLpPb(3,0,2);
encoder.SetEndMarkerMode(false);
encoder.WriteCoderProperties(outputStream);
long fileSize;
fileSize = inputToCompress.length();
for (int i = 0; i < 8; i++)
{
outputStream.write((int) (fileSize >>> (8 * i)) & 0xFF);
}
encoder.Code(inputStream, outputStream, -1, -1, null);
// free resources
outputStream.flush();
outputStream.close();
inputStream.close();
}
}
The SKD for the SevenZip packages come from the offical SKD. Download it here ;).
Disclaimer: I believe, I found that snippet a while ago on the net...but I don't found the source anymore.