Adding files to ZIP file - java

I am trying to add some files to a ZIP file, it creates the file but does not add anything into it.
Code 1:
String fulldate = year + "-" + month + "-" + day + "-" + min;
File dateFolder = new File("F:\\" + compname + "\\" + fulldate);
dateFolder.mkdir();
String zipName = "F:\\" + compname + "\\" + fulldate + "\\" + fulldate + ".zip";
zipFolder(tobackup, zipName);
My function:
public static void zipFolder(File folder, String name) throws Exception {
byte[] buffer = new byte[18024];
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(name));
FileInputStream in = new FileInputStream(folder);
out.putNextEntry(new ZipEntry(name));
int len;
while((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
out.close();
}
Edit: I found the problem, it was just having trouble writing files from the C:\ drive into a ZIP in the F:\ drive

You can't zip folders, only files. To zip folders, you have to add all the subfiles manually. I wrote this class that does the job. You can have it for free :)
The usage would be this:
List<File> sources = new ArrayList<File>();
sources.add(tobackup);
Packager.packZip(new File(zipName), sources);
Here is the class:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Packager
{
public static void packZip(File output, List<File> sources) throws IOException
{
System.out.println("Packaging to " + output.getName());
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output));
zipOut.setLevel(Deflater.DEFAULT_COMPRESSION);
for (File source : sources)
{
if (source.isDirectory())
{
zipDir(zipOut, "", source);
} else
{
zipFile(zipOut, "", source);
}
}
zipOut.flush();
zipOut.close();
System.out.println("Done");
}
private static String buildPath(String path, String file)
{
if (path == null || path.isEmpty())
{
return file;
} else
{
return path + "/" + file;
}
}
private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException
{
if (!dir.canRead())
{
System.out.println("Cannot read " + dir.getCanonicalPath() + " (maybe because of permissions)");
return;
}
File[] files = dir.listFiles();
path = buildPath(path, dir.getName());
System.out.println("Adding Directory " + path);
for (File source : files)
{
if (source.isDirectory())
{
zipDir(zos, path, source);
} else
{
zipFile(zos, path, source);
}
}
System.out.println("Leaving Directory " + path);
}
private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException
{
if (!file.canRead())
{
System.out.println("Cannot read " + file.getCanonicalPath() + " (maybe because of permissions)");
return;
}
System.out.println("Compressing " + file.getName());
zos.putNextEntry(new ZipEntry(buildPath(path, file.getName())));
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4092];
int byteCount = 0;
while ((byteCount = fis.read(buffer)) != -1)
{
zos.write(buffer, 0, byteCount);
System.out.print('.');
System.out.flush();
}
System.out.println();
fis.close();
zos.closeEntry();
}
}
Enjoy!
EDIT: To check if the program is still busy, you can add the three lines I marked with a (*)
EDIT 2: Try the new code. On my platform, it runs correct (OS X). I'm not sure but, there might be some limited read permissions for files in Windows in AppData.

See also ZeroTurnaround's Zip library. It has such features as (citation):
pack and unpack directories recursively
iterate through ZIP entries

I'll add another way using Java 7 NIO FileSystem. It uses the fact that JAR files are actually ZIP:
static public void addToZip(Path zip, Path file) throws IOException {
Map<String,String> env = new HashMap<>();
env.put("create", "false"); // We don't create the file but modify it
URI uri = URI.create("jar:file:"+zip.toString());
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path f = zipfs.getPath(file.getFileName().toString());
Files.copy(file, f, StandardCopyOption.REPLACE_EXISTING);
}
}

Related

Create file in zip format [duplicate]

I have a dynamic text file that picks content from a database according to the user's query. I have to write this content into a text file and zip it in a folder in a servlet. How should I do this?
Look at this example:
StringBuilder sb = new StringBuilder();
sb.append("Test String");
File f = new File("d:\\test.zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
ZipEntry e = new ZipEntry("mytext.txt");
out.putNextEntry(e);
byte[] data = sb.toString().getBytes();
out.write(data, 0, data.length);
out.closeEntry();
out.close();
This will create a zip in the root of D: named test.zip which will contain one single file called mytext.txt. Of course you can add more zip entries and also specify a subdirectory like this:
ZipEntry e = new ZipEntry("folderName/mytext.txt");
You can find more information about compression with Java here.
Java 7 has ZipFileSystem built in, that can be used to create, write and read file from zip file.
Java Doc: ZipFileSystem Provider
Map<String, String> env = new HashMap<>();
// Create the zip file if it doesn't exist
env.put("create", "true");
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt");
Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");
// Copy a file into the zip file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
To write a ZIP file, you use a ZipOutputStream. For each entry that you want to place into the ZIP file, you create a ZipEntry object. You pass the file name to the ZipEntry constructor; it sets the other parameters such as file date and decompression method. You can override these settings if you like. Then, you call the putNextEntry method of the ZipOutputStream to begin writing a new file. Send the file data to the ZIP stream. When you are done, call closeEntry. Repeat for all the files you want to store. Here is a code skeleton:
FileOutputStream fout = new FileOutputStream("test.zip");
ZipOutputStream zout = new ZipOutputStream(fout);
for all files
{
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();
}
zout.close();
Here is an example code to compress a Whole Directory(including sub files and sub directories), it's using the walk file tree feature of Java NIO.
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipCompress {
public static void compress(String dirPath) {
final Path sourceDir = Paths.get(dirPath);
String zipFileName = dirPath.concat(".zip");
try {
final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = sourceDir.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
To use this, just call
ZipCompress.compress("target/directoryToCompress");
and you'll get a zip file directoryToCompress.zip
Single file:
String filePath = "/absolute/path/file1.txt";
String zipPath = "/absolute/path/output.zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
Multiple files:
List<String> filePaths = Arrays.asList("/absolute/path/file1.txt", "/absolute/path/file2.txt");
String zipPath = "/absolute/path/output.zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
for (String filePath : filePaths) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
}
Spring boot controller, zip the files in a directory, and can be downloaded.
#RequestMapping(value = "/files.zip")
#ResponseBody
byte[] filesZip() throws IOException {
File dir = new File("./");
File[] filesArray = dir.listFiles();
if (filesArray == null || filesArray.length == 0)
System.out.println(dir.getAbsolutePath() + " have no file!");
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ZipOutputStream zipOut= new ZipOutputStream(bo);
for(File xlsFile:filesArray){
if(!xlsFile.isFile())continue;
ZipEntry zipEntry = new ZipEntry(xlsFile.getName());
zipOut.putNextEntry(zipEntry);
zipOut.write(IOUtils.toByteArray(new FileInputStream(xlsFile)));
zipOut.closeEntry();
}
zipOut.close();
return bo.toByteArray();
}
This is how you create a zip file from a source file:
String srcFilename = "C:/myfile.txt";
String zipFile = "C:/myfile.zip";
try {
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(srcFilename);
FileInputStream fis = new FileInputStream(srcFile);
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
zos.close();
}
catch (IOException ioe) {
System.out.println("Error creating zip file" + ioe);
}
public static void main(String args[])
{
omtZip("res/", "omt.zip");
}
public static void omtZip(String path,String outputFile)
{
final int BUFFER = 2048;
boolean isEntry = false;
ArrayList<String> directoryList = new ArrayList<String>();
File f = new File(path);
if(f.exists())
{
try {
FileOutputStream fos = new FileOutputStream(outputFile);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte data[] = new byte[BUFFER];
if(f.isDirectory())
{
//This is Directory
do{
String directoryName = "";
if(directoryList.size() > 0)
{
directoryName = directoryList.get(0);
System.out.println("Directory Name At 0 :"+directoryName);
}
String fullPath = path+directoryName;
File fileList = null;
if(directoryList.size() == 0)
{
//Main path (Root Directory)
fileList = f;
}else
{
//Child Directory
fileList = new File(fullPath);
}
String[] filesName = fileList.list();
int totalFiles = filesName.length;
for(int i = 0 ; i < totalFiles ; i++)
{
String name = filesName[i];
File filesOrDir = new File(fullPath+name);
if(filesOrDir.isDirectory())
{
System.out.println("New Directory Entry :"+directoryName+name+"/");
ZipEntry entry = new ZipEntry(directoryName+name+"/");
zos.putNextEntry(entry);
isEntry = true;
directoryList.add(directoryName+name+"/");
}else
{
System.out.println("New File Entry :"+directoryName+name);
ZipEntry entry = new ZipEntry(directoryName+name);
zos.putNextEntry(entry);
isEntry = true;
FileInputStream fileInputStream = new FileInputStream(filesOrDir);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER);
int size = -1;
while( (size = bufferedInputStream.read(data, 0, BUFFER)) != -1 )
{
zos.write(data, 0, size);
}
bufferedInputStream.close();
}
}
if(directoryList.size() > 0 && directoryName.trim().length() > 0)
{
System.out.println("Directory removed :"+directoryName);
directoryList.remove(0);
}
}while(directoryList.size() > 0);
}else
{
//This is File
//Zip this file
System.out.println("Zip this file :"+f.getPath());
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis,BUFFER);
ZipEntry entry = new ZipEntry(f.getName());
zos.putNextEntry(entry);
isEntry = true;
int size = -1 ;
while(( size = bis.read(data,0,BUFFER)) != -1)
{
zos.write(data, 0, size);
}
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
if(isEntry)
{
zos.close();
}else
{
zos = null;
System.out.println("No Entry Found in Zip");
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
}catch(Exception e)
{
e.printStackTrace();
}
}else
{
System.out.println("File or Directory not found");
}
}
}
Given exportPath and queryResults as String variables, the following block creates a results.zip file under exportPath and writes the content of queryResults to a results.txt file inside the zip.
URI uri = URI.create("jar:file:" + exportPath + "/results.zip");
Map<String, String> env = Collections.singletonMap("create", "true");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path filePath = zipfs.getPath("/results.txt");
byte[] fileContent = queryResults.getBytes();
Files.write(filePath, fileContent, StandardOpenOption.CREATE);
}
You have mainly to create two functions. First is writeToZipFile() and second is createZipfileForOutPut .... and then call the createZipfileForOutPut('file name of .zip')` …
public static void writeToZipFile(String path, ZipOutputStream zipStream)
throws FileNotFoundException, IOException {
System.out.println("Writing file : '" + path + "' to zip file");
File aFile = new File(path);
FileInputStream fis = new FileInputStream(aFile);
ZipEntry zipEntry = new ZipEntry(path);
zipStream.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipStream.write(bytes, 0, length);
}
zipStream.closeEntry();
fis.close();
}
public static void createZipfileForOutPut(String filename) {
String home = System.getProperty("user.home");
// File directory = new File(home + "/Documents/" + "AutomationReport");
File directory = new File("AutomationReport");
if (!directory.exists()) {
directory.mkdir();
}
try {
FileOutputStream fos = new FileOutputStream("Path to your destination" + filename + ".zip");
ZipOutputStream zos = new ZipOutputStream(fos);
writeToZipFile("Path to file which you want to compress / zip", zos);
zos.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
There is another option by using zip4j at https://github.com/srikanth-lingala/zip4j
Creating a zip file with single file in it / Adding single file to an existing zip
new ZipFile("filename.zip").addFile("filename.ext");
Or
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Creating a zip file with multiple files / Adding multiple files to an existing zip
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Creating a zip file by adding a folder to it / Adding a folder to an existing zip
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Creating a zip file from stream / Adding a stream to an existing zip
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
I know this question is answered but if you have a list of strings and you want to create a separate file for each string in the archive, you can use the snippet below.
public void zipFileTest() throws IOException {
Map<String, String> map = Map.ofEntries(
new AbstractMap.SimpleEntry<String, String>("File1.txt", "File1 Content"),
new AbstractMap.SimpleEntry<String, String>("File2.txt", "File2 Content"),
new AbstractMap.SimpleEntry<String, String>("File3.txt", "File3 Content")
);
createZipFileFromStringContents(map, "archive.zip");
}
public void createZipFileFromStringContents(Map<String, String> map, String zipfilePath) throws IOException {
FileOutputStream fout = new FileOutputStream(zipfilePath);
ZipOutputStream zout = new ZipOutputStream(fout);
for (Map.Entry<String, String> entry : map.entrySet()) {
String fileName = entry.getKey();
ZipEntry zipFile = new ZipEntry(fileName);
zout.putNextEntry(zipFile);
String fileContent = entry.getValue();
zout.write(fileContent.getBytes(), 0, fileContent.getBytes().length);
zout.closeEntry();
}
zout.close();
}
It will create a zip file with the structure as in the below image:
Here is my working solution:
public static byte[] createZipFile(Map<String, FileData> files) throws IOException {
try(ByteArrayOutputStream tZipFile = new ByteArrayOutputStream()) {
try (ZipOutputStream tZipFileOut = new ZipOutputStream(tZipFile)) {
for (Map.Entry<String, FileData> file : files.entrySet()) {
ZipEntry zipEntry = new ZipEntry(file.getValue().getFileName());
tZipFileOut.putNextEntry(zipEntry);
tZipFileOut.write(file.getValue().getBytes());
}
}
return tZipFile.toByteArray();
}
}
public class FileData {
private String fileName;
private byte[] bytes;
public String getFileName() {
return this.fileName;
}
public byte[] getBytes() {
return this.bytes;
}
}
This will create byte[] of ZIP file which contains one or more compressed files. I've used this method inside controller method and write bytes[] of ZIP file into response to download ZIP file(s) from server.
Since it took me a while to figure it out, I thought it would be helpful to post my solution using Java 7+ ZipFileSystem
openZip(runFile);
addToZip(filepath); //loop construct;
zipfs.close();
private void openZip(File runFile) throws IOException {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
env.put("encoding", "UTF-8");
Files.deleteIfExists(runFile.toPath());
zipfs = FileSystems.newFileSystem(URI.create("jar:" + runFile.toURI().toString()), env);
}
private void addToZip(String filename) throws IOException {
Path externalTxtFile = Paths.get(filename).toAbsolutePath();
Path pathInZipfile = zipfs.getPath(filename.substring(filename.lastIndexOf("results"))); //all files to be stored have a common base folder, results/ in my case
if (Files.isDirectory(externalTxtFile)) {
Files.createDirectories(pathInZipfile);
try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalTxtFile)) {
for (Path child : ds) {
addToZip(child.normalize().toString()); //recursive call
}
}
} else {
// copy file to zip file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
}
public static void zipFromTxt(String zipFilePath, String txtFilePath) {
Assert.notNull(zipFilePath, "Zip file path is required");
Assert.notNull(txtFilePath, "Txt file path is required");
zipFromTxt(new File(zipFilePath), new File(txtFilePath));
}
public static void zipFromTxt(File zipFile, File txtFile) {
ZipOutputStream out = null;
FileInputStream in = null;
try {
Assert.notNull(zipFile, "Zip file is required");
Assert.notNull(txtFile, "Txt file is required");
out = new ZipOutputStream(new FileOutputStream(zipFile));
in = new FileInputStream(txtFile);
out.putNextEntry(new ZipEntry(txtFile.getName()));
int len;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
} catch (Exception e) {
log.info("Zip from txt occur error,Detail message:{}", e.toString());
} finally {
try {
if (in != null) in.close();
if (out != null) {
out.closeEntry();
out.close();
}
} catch (Exception e) {
log.info("Zip from txt close error,Detail message:{}", e.toString());
}
}
}
Using Jeka https://jeka.dev JkPathTree, it's quite straightforward.
Path wholeDirToZip = Paths.get("dir/to/zip");
Path zipFile = Paths.get("file.zip");
JkPathTree.of(wholeDirToZip).zipTo(zipFile);
If you want decompress without software better use this code. Other code with pdf files sends error on manually decompress
byte[] buffer = new byte[1024];
try {
FileOutputStream fos = new FileOutputStream("123.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry("file.pdf");
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream("file.pdf");
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
} catch(IOException ex) {
ex.printStackTrace();
}

Unzipping in java, every file unzips except for one

I am building a library for android, and it requires me to unzip files. It works on every single other file except for one file in one particular archive. I get a file not found exception on this. I am not a java expert, or an android expert, but my team is also stumped. Just hoping someone can spot something in my code that could be creating a bug.
public static void unzip(File zipFile,
String unzipFilePath,
FetchInterface responseHandler,
JSONObject json) {
final int BUFFER_SIZE = 4096;
String filename;
InputStream inputStream;
ZipInputStream zipInputStream;
ZipEntry zipEntry = null;
String path = unzipFilePath + File.separator;
try {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
String zipRootDirectory = null;
inputStream = new FileInputStream(zipFile);
zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream));
byte[] buffer = new byte[BUFFER_SIZE];
int count;
// Log.d(tag, zipFile.getName());
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
filename = zipEntry.getName();
Log.d(tag, "ZIP ENTRY: " + zipEntry.getName());
if (zipRootDirectory == null) {
zipRootDirectory = zipEntry.getName().split("\\/")[0];
// Log.d(tag, "ROOT DIR: " + zipRootDirectory);
}
if (zipEntry.isDirectory()) {
Log.d(tag, "ZIPENTRY IS DIR: " + zipEntry.toString());
File fmd = new File(path + filename);
fmd.mkdirs();
continue;
}
try {
FileOutputStream fout = new FileOutputStream(path + filename);
Log.e(tag, "FILENAME: " + filename);
while ((count = zipInputStream.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
} catch(FileNotFoundException e) {
Log.e(tag, "ERROR AT THIS FILE: " + filename);
e.printStackTrace();
}
zipInputStream.closeEntry();
}
zipInputStream.close();
File zipRootDirectoryFile = new File(path + File.separator + zipRootDirectory);
if (zipRootDirectoryFile.exists()) {
Log.d(tag, zipRootDirectoryFile.getName());
File renameFile = new File(path + File.separator + "html" + File.separator);
zipRootDirectoryFile.renameTo(renameFile);
} else {
Log.e(tag, "directory cannot be renamed as it does not exist");
}
} catch (IOException e) {
e.getStackTrace();
}
}

java.io.FileNotFoundException: (Access is denied) when i have permission to the file

so I'm getting this error:
java.io.FileNotFoundException: C:\Users\censored\Documents\Electrocode Productions\template\resources\images (Access is denied)
when I run this code:
package com.template;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Copy {
static File folder = new File(System.getProperty("user.home") + "/Documents/Electrocode Productions/template");
public static void writeSaves() {
File imagesFile = new File(folder + "/resources/images");
if(!imagesFile.exists()) {
try {
InputStream input = (Main.class.getResourceAsStream("/resources/images"));
BufferedInputStream buffedInput = new BufferedInputStream(input);
File fileFolder = new File(folder + "/resources/images");
try {
fileFolder.mkdirs();
} catch(SecurityException e) {
Log.error(e);
}
OutputStream output = new FileOutputStream(fileFolder);
BufferedOutputStream buffedOutput = new BufferedOutputStream(output);
byte[] buffer = new byte[input.available()];
System.out.println(buffer);
int bytesRead;
while((bytesRead = buffedInput.read(buffer)) > 0 ) {
buffedOutput.write(buffer, 0, bytesRead);
}
input.close();
output.close();
} catch(IOException e) {
Log.error(e);
}
}
despite the fact that I'm pretty sure I have access to write to the file as in another section of my code I do this:
public static void dump() {
if(!folder.exists()) {
try {
folder.mkdirs();
} catch(SecurityException e) {
Log.error(e);
}
}
Path oldFilePath = Paths.get(folder + "/latest.log");
Path newFilePath = Paths.get(folder + "/" + time.getDayOfMonth() + "." + time.getMonth() + "." + time.getYear() + "_" + time.getHour() + "." + time.getMinute() + "." + time.getSecond() + ".log");
if(Config.get("keeplogs").equals("true")) {
try(BufferedWriter writer = Files.newBufferedWriter(newFilePath, StandardOpenOption.CREATE, StandardOpenOption.APPEND, StandardOpenOption.WRITE)) {
#SuppressWarnings("resource")
Scanner scanner = new Scanner(oldFilePath);
while(scanner.hasNextLine()) {
writer.write(scanner.nextLine());
writer.newLine();
}
} catch(IOException e) {
e.printStackTrace();
}
} else if(Config.get("keeplogs").equals("false")) {
} else {
Log.warning("Unknown argument " + Config.get("log") + " in config.properties. Must be true or false");
}
}
What am I doing wrong? This maybe a duplicate but it may not be as I've looked at everything I can find on here (StackOverflow) and tried it all. Nothing seems to be working.
It seems that you created C:\Users\censored\Documents\Electrocode Productions\template\resources\images directory with mkdirs call. Then you trying to open it like a file what obviously fails.
Here is the code that answered my question:
public static void writeSaves(File src, File dest) throws IOException {
if(src.isDirectory()){
//if directory not exists, create it
if(!dest.exists()){
dest.mkdirs();
}
//list all the directory contents
String files[] = src.list();
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
writeSaves(srcFile,destFile);
}
}else{
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
}
Thank you all who tried to help!

Java renaming files in directory doesn't work properly

I am trying to rename to upper case all the files in a given directory. It does the whole thing but it doesn't do anything in the folder file names are still the same .
import java.io.File;
import java.io.IOException;
public class FileOps {
public static void main(String[] argv) throws IOException {
File folder = new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
File f = new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files"
+ listOfFiles[i].getName());
f.renameTo(new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files"
+ listOfFiles[i].getName().toUpperCase()
+ ".txt"));
}
}
System.out.println("Done");
}
}
It prints "Done" in the console but nothing is really done
In your if statement, you forgot to add ending separator:
if (listOfFiles[i].isFile()) {
File f = new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files\\"// <- Missing separator
+ listOfFiles[i].getName());
f.renameTo(new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files\\"// <- Missing separator
+ listOfFiles[i].getName().toUpperCase()
+ ".txt"));
}
A proper implemntation would be:
if (listOfFiles[i].isFile())
listOfFiles[i].renameTo(new File(folder, listOfFiles[i].getName().toUpperCase()+ ".txt"));//not sure why this .txt
Be careful, the renameTo method is highly platform dependent. Read the Javadoc
You might use the following to check what is happening. Some small changes include using the File(parent,name) form to avoid having to determine and add the OS specific file path separator.
package com.example.renaming;
import java.io.File;
import java.io.IOException;
public class TestRename {
private static final String[] defaultArgs = { "C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files" };
private static TestRename me;
private static String[] arguments;
public static void main(String[] args) {
me = new TestRename();
if (args == null | args.length == 0) {
arguments = defaultArgs;
} else {
arguments = args;
}
me.doWork(arguments);
}
private void doWork(String[] arguments) {
int numFiles = 0;
File folder = new File(arguments[0]);
try {
System.out.println("Working on " + folder.getCanonicalPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File[] fileList = folder.listFiles();
if (fileList == null) {
System.out.println("No files fould");
} else {
for (int i = 0; i < fileList.length; i++) {
System.out.println("File " + fileList[i].getName());
if (fileList[i].isFile()) {
numFiles++;
try {
String currentName = fileList[i].getName();
File parent = fileList[i].getParentFile();
String newName = currentName.toUpperCase() + ".txt";
System.out.println(" .. current = " + currentName);
System.out.println(" .. newname = " + newName);
// Avoids having to get the file path separator for an OS
File newFile = new File(parent, newName);
System.out.println(" .. new File = "
+ newFile.getCanonicalPath());
fileList[i].renameTo(newFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("Done, found " + numFiles);
}
}
}
As pointed by ortis, you have missed to add "\" while naming files.
f.renameTo(new File(
"C:\\Users\\N\\Desktop\\New folder\\RenamingFiles\\src\\renaming\\Files"
+ listOfFiles[i].getName().toUpperCase()
+ ".txt"));
executing this code over and over will result in adding .txt to the file names. You can consider using apache FileUtils for getting extention.
Making those changes to your code,
File folder = new File("/home/ubuntu/Desktop/pics");
File[] listOfFiles = folder.listFiles();
for(File file : listOfFiles){
if(file.isFile()){
String fileName = FilenameUtils.removeExtension(file.getName()).toUpperCase() ;
String newPath = folder + File.separator + fileName+ "."+ FilenameUtils.getExtension(file.getName());
file.renameTo(new File(newPath));
}
}

Compressing a folder into a ZipFile

I have this Java method to upload a file. I am trying to cater for users trying to upload a folder by compressing that folder into a zip file and upload it instead. For some reason in my case file.isDirectory() and file.isFile() are not working correctly.. even though the filename does not contain any extension, file.isFile() is returning true and isDirectory() returns false. Also directory.list() is also acting weird by returning null.
What can be the problem? Am I doing something wrong?
public File uploadFile(FileItem item, String filename, int ticket_id) throws IOException
{
FileOutputStream out = null;
InputStream fileContent = null;
File file = null;
try
{
//fullpath returns C://MyDocuments//zerafbe//Documents//apache-tomcat-7.0.29//webapps//attachments//t50\test
StringBuffer fullPath = new StringBuffer();
fullPath.append(Attachment.attachments_path);
fullPath.append("t");
fullPath.append(Integer.toString(ticket_id));
fullPath.append(File.separator);
fullPath.append(filename);
System.out.println("filename " + filename);
file = new File(fullPath.toString());
if (!file.exists())
{
// if directory does not exist, create it
file.getParentFile().mkdirs();
}
if (file.isFile())
{
// if file is not a folder
out = new FileOutputStream(file);
fileContent = item.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
// read all the file and write it to created file
while ((read = fileContent.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
}
else if (file.isDirectory())
{
ZipFile appZip = new ZipFile(fullPath.toString());
appZip.generateFileList(file);
appZip.zipIt(filename + ".zip");
}
}
catch (FileNotFoundException e)
{
LogFile.logError("[FileUpload.uploadFile()] " + e.getMessage());
}
catch (IOException e1)
{
LogFile.logError("[FileUpload.uploadFile()] " + e1.getMessage());
}
finally
{
if (out != null)
{
out.close();
}
if (fileContent != null)
{
fileContent.close();
}
}
return file;
}
This is the ZipFile class I am using
public class ZipFile
{
List<String> fileList = null;
String source_folder = "";
public ZipFile(String source_folder)
{
fileList = new ArrayList<String>();
this.source_folder = source_folder;
}
public void zipIt(String zipFile)
{
byte[] buffer = new byte[1024];
String source = "";
try
{
try
{
source = source_folder.substring(source_folder.lastIndexOf("\\") + 1, source_folder.length());
}
catch(Exception e)
{
source = source_folder;
}
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
for (String file : this.fileList)
{
ZipEntry ze = new ZipEntry(source + File.separator + file);
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(source_folder + File.separator + file);
int len;
while ((len = in.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
in.close();
}
zos.closeEntry();
//remember close it
zos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
public void generateFileList(File node)
{
// add file only
if(node.isFile())
{
fileList.add(generateZipEntry(node.toString()));
}
if(node.isDirectory())
{
String[] subNode = node.list();
if (subNode != null) {
for(String filename : subNode)
{
generateFileList(new File (node, filename));
}
}
}
}
private String generateZipEntry(String path)
{
return path.substring(source_folder.length() + 1, path.length());
}
}
file.list() is being done in the generateFileList method in ZipFile class. I know this is returning null since I tried detecting whether the file is a folder or a file by using filename.indexOf(".") instead of isDirectory() and isFile() since they were not working. But I wish I had an explanation for this.
Thanks for your help!
if (!file.exists()) {
// if directory does not exist, create it
file.mkdirs();
}
will create directory and test file.isDirectory() will return true
It could be a problem with the path?
C://MyDocuments//zerafbe//Documents//apache-tomcat-7.0.29//webapps//attachments//t50\test
You are mixing backslash with slash...
I tested your code block
ZipFile appZip = new ZipFile(file.toString());
appZip.generateFileList(file);
appZip.zipIt(filename + ".zip");
with a local folder and it's working perfectly. I think you are passing a invalid path. This may be the cause isFile or isDirectory methods are acting strangely. Try to add a validation statement at the starting of generateFileList method using File API:
if(!node.exists) {
// return some flag to signify error OR throw a suitable Exception
}
This should work.
public String compressData(String srcDir) {
String zipFile = srcDir+".zip";
try {
// create byte buffer
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File dir = new File(srcDir);
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
System.out.println("Adding file: " + files[i].getName());
FileInputStream fis = new FileInputStream(files[i]);
// begin writing a new ZIP entry, positions the stream to the start of the entry data
zos.putNextEntry(new ZipEntry(files[i].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);
}
return zipFile;
}

Categories