Is this an efficient way to copy all files with in a directory, including child directories? Is there a chance of infinite recursion? Is there anything I should change? I know it works, but I think there should be an easier way to do this.
private void copy(File file, String path) {
String fileName = file.getPath();
System.out.println(fileName);
fileName = fileName.substring(fileName.lastIndexOf("\\"));
if (path == null)
path = Storage.getStorageDirectoryPath();
File toWrite = new File(path + File.separator + fileName);
if (file.isDirectory()) {
toWrite.mkdir();
File inDirectory[] = file.listFiles();
for (File f : inDirectory)
copy(f, toWrite.getPath());
} else {
try {
InputStream inStream = new FileInputStream(file);
OutputStream outStream = new FileOutputStream(toWrite);
byte buffer[] = new byte[1024];
int length = 0;
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
inStream.close();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks
Looks pretty good as the comments indicate. You might want to look into the new Java 7 API's (the new NIO). There's a tutorial here, it looks like there are even options to avoid following links.
If you can't use Java 7, old NIO has channels that you can open after opening the file the old way. They include methods transferFrom and transferTo, which might be able to do it more efficiently than you could in Java.
Why reinvent the wheel? take a look at the methods in Apache Common's FileUtils, in particular copyDirectory.
Related
I am doing a program which will receiving any file from my remote server, these files can be .doc, .pdf and some others file type. I will read the content in those files and write it into another new files with same file extension. But when i receive a .doc file from remote server and i try read the file and write into another file, it's show me something like this #²Ó\ç¨ Þ¢·S \Ò Þ¢·S \Ò PK £ JT in my test.doc. i have no idea on this issues, i try PrintStream,BufferedWriter or PrintWriter but unfortunately it's wouldn't help anything This is my source code for read/write the file
try
{
InputStream is1 = con1.getInputStream();
BufferedReader read1 = new BufferedReader (new InputStreamReader(is1));
String data1 = "" ;
while ((data1 = read1.readLine()) != null)
{
PrintWriter pw = new PrintWriter("test.doc","UTF-8");
pw.write(data1);
pw.close();
}
System.out.println("done");
}
catch(IOException e)
{
e.printStackTrace();
}
May i know what is the best way to do the read/write if we having difference file type ?
These file types have binary data and should not be read as characters. (Also, note that you are creating a new PrintWriter every time through the while loop. This will never work.) Just deal with the binary data directly. Something like this (untested) might work:
InputStream is1 = con1.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is1);
byte[] buffer = new byte[2048]; // or whatever size you want
int n;
OutputStream os = new FileOutputStream("test.doc");
while ((n = bis.read(buffer)) >= 0) {
os.write(buffer, 0, n);
}
os.close();
bis.close();
Also, you should be using a try with resources statement.
Other approach (more concise, more expressive):
Files.copy(is1, Paths.get("test.doc"), StandardCopyOption.REPLACE_EXISTING);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Appending files to a zip file with Java
Hello Java Developers,
Here's the scenario:
Say I have a textfile named sample.txt. What I actually want to do is to put the sample.txt file into a *.zip file named TextFiles.zip.
Here's what I have learned so far.
try{
File f = new File(compProperty.getZIP_OUTPUT_PATH());
zipOut = new ZipOutputStream(new FileOutputStream(f));
ZipEntry zipEntry = new ZipEntry("sample.txt");
zipOut.putNextEntry(zipEntry);
zipOut.closeEntry();
zipOut.close();
System.out.println("Done");
} catch ( Exception e ){
// My catch block
}
My code so far creates a *.zip file and insert the sample.txt file.
My question is how would I be able to insert an existing file to the created *.zip file?
If your answer has anything to do with TrueZIP, please post an SSCCE.
I have done the following:
Googled
Search for existing question. ( Found few. No answer. Some didn't answer my particular question.
Read TrueZip. Yet, I couldn't understand a thing. ( Please do understand )
Using the inbuilt Java API. This will add a file to a Zip File, this will replace any existing Zip files that may exist, creating a new Zip file.
public class TestZip02 {
public static void main(String[] args) {
try {
zip(new File("TextFiles.zip"), new File("sample.txt"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void zip(File zip, File file) throws IOException {
ZipOutputStream zos = null;
try {
String name = file.getName();
zos = new ZipOutputStream(new FileOutputStream(zip));
ZipEntry entry = new ZipEntry(name);
zos.putNextEntry(entry);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] byteBuffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = fis.read(byteBuffer)) != -1) {
zos.write(byteBuffer, 0, bytesRead);
}
zos.flush();
} finally {
try {
fis.close();
} catch (Exception e) {
}
}
zos.closeEntry();
zos.flush();
} finally {
try {
zos.close();
} catch (Exception e) {
}
}
}
}
Here you can get answer for your question: http://truezip.schlichtherle.de/2011/07/26/appending-to-zip-files/
It seems that, according to the epic JDK reference, you could use a while zis.getNextEntry() != null loop to loop through the file (where zis is a ZipInputStream), then use zis.read() to read into an array, which is sent to an ArrayList or similar.
Then, one could use toArray(), "cast" it to a byte array with this method and zos.write() it into the output ZIP file (where zos is a ZipOutputStream), using zos.putNextEntry() to make new entries. (You will need to save the ZipEntry and get its name with ze.getName(), with ze being a ZipEntry.)You should replace T with Byte and byte (use byte everywhere but the for loop body) and may need to modify the casting code to use Byte.byteValue() to convert from Byte (wrapper class) to byte (primitive type), like so:
for(int i = 0; i < objects.length; i++) {
convertedObjects[i] = (Byte)objects[i].byteValue();
}
Note that this is untested and based on the JDK (entries ZipInputStream, ZipOutputStream, ArrayList, and Byte) and a Google search on array casting.
Sorry if that was a bit dense, and hope this helps!!
I have been working on this for quite a few hours. I can't seem to find the issue to this problem. Essentially what I have is this:
I have a jar, let's call it "a.jar"
I need to get the directory "z" and it's contents from "a.jar", but "z" isn't in the root directory of "a.jar".
"z" is in "/x/y/" and "/x/y/" is in "a.jar", so it looks like this:
"a.jar/x/y/z/"
I hope that's a decent explanation. By the way, "a.jar" is what everything is running out of, so its in the class path obviously.
Basically for each ZipEntry you have to check if it isDirectory() and parse that also.
Checkout this link:
http://www.javaworld.com/javaworld/javatips/jw-javatip49.html
LE:
Here is a complete example that extracts the files from the jar, and if you specify a specific path it will extract only that folder:
public void doUnzip(String inputZip, String destinationDirectory, String specificPath)
throws IOException {
int BUFFER = 2048;
File sourceZipFile = new File(inputZip);
File unzipDestinationDirectory = new File(destinationDirectory);
unzipDestinationDirectory.mkdir();
ZipFile zipFile;
// Open Zip file for reading
zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ);
// Create an enumeration of the entries in the zip file
Enumeration<?> zipFileEntries = zipFile.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
if(specificPath != null){
if(entry.getName().startsWith(specificPath) == false)
continue;
}
File destFile = new File(unzipDestinationDirectory, entry.getName());
// create the parent directory structure if needed
destFile.getParentFile().mkdirs();
try {
// extract file if not a directory
if (!entry.isDirectory()) {
BufferedInputStream is = new BufferedInputStream(
zipFile.getInputStream(entry));
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos,
BUFFER);
// read and write until last byte is encountered
for (int bytesRead; (bytesRead = is.read(data, 0, BUFFER)) != -1;) {
dest.write(data, 0, bytesRead);
}
dest.flush();
dest.close();
is.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
zipFile.close();
}
public static void main(String[] args) {
Unzip unzip = new Unzip();
try {
unzip.doUnzip("test.jar", "output", "x/y/z");
} catch (IOException e) {
e.printStackTrace();
}
}
..(ZipEntry), but they don't work very well with sub-directories.
They work just fine. Iterate the entries and simply check the path equates to that sub-directory. If it does, add it to a list (or process it, whatever).
Basically, I have a jar file that i want to unzip to a specific folder from a junit test.
What is the easiest way to do this?
I am willing to use a free third party library if it's necessary.
You could use java.util.jar.JarFile to iterate over the entries in the file, extracting each one via its InputStream and writing the data out to an external File. Apache Commons IO provides utilities to make this a bit less clumsy.
ZipInputStream in = null;
OutputStream out = null;
try {
// Open the jar file
String inFilename = "infile.jar";
in = new ZipInputStream(new FileInputStream(inFilename));
// Get the first entry
ZipEntry entry = in.getNextEntry();
// Open the output file
String outFilename = "o";
out = new FileOutputStream(outFilename);
// Transfer bytes from the ZIP file to the output file
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} catch (IOException e) {
// Manage exception
} finally {
// Close the streams
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
Jar is basically zipped using ZIP algorithm, so you can use winzip or winrar to extract.
If you are looking for programmatic way then the first answer is more correct.
From command line type jar xf foo.jar or unzip foo.jar
Use the Ant unzip task.
Here's my version in Scala, would be the same in Java, that unpacks into separate files and directories:
import java.io.{BufferedInputStream, BufferedOutputStream, ByteArrayInputStream}
import java.io.{File, FileInputStream, FileOutputStream}
import java.util.jar._
def unpackJar(jar: File, target: File): Seq[File] = {
val b = Seq.newBuilder[File]
val in = new JarInputStream(new BufferedInputStream(new FileInputStream(jar)))
try while ({
val entry: JarEntry = in.getNextJarEntry
(entry != null) && {
val f = new File(target, entry.getName)
if (entry.isDirectory) {
f.mkdirs()
} else {
val bs = new BufferedOutputStream(new FileOutputStream(f))
try {
val arr = new Array[Byte](1024)
while ({
val sz = in.read(arr, 0, 1024)
(sz > 0) && { bs.write(arr, 0, sz); true }
}) ()
} finally {
bs.close()
}
}
b += f
true
}
}) () finally {
in.close()
}
b.result()
}
I need to (un)zip some files and after some googling I haven't found any utility for doing it. I know I can do it with built-in java.uitl.zip.* classes but isn't there any utility, that will make it easer, best like this:
SomeClass.unzip("file_name.zip", "target_directory");
or
SomeClass.zip("source_directory", "target_file_name.zip", recursively);
I don't want to handle streams. Just file, or better just file names...
How about the Deflater/Inflater classes mentioned in the question "What’s a good compression library for Java?".
I know the current interfaces proposed by Java are Stream-based, not "filename"-based, but according to the following article on Java compression, it is easy enough to build an utility class around that:
For instance, a Unzip function based on a filename would look like:
import java.io.*;
import java.util.zip.*;
public class UnZip {
final int BUFFER = 2048;
public static void main (String argv[]) {
try {
BufferedOutputStream dest = null;
FileInputStream fis = new
FileInputStream(argv[0]);
ZipInputStream zis = new
ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while((entry = zis.getNextEntry()) != null) {
System.out.println("Extracting: " +entry);
int count;
byte data[] = new byte[BUFFER];
// write the files to the disk
FileOutputStream fos = new
FileOutputStream(entry.getName());
dest = new
BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER))
!= -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
zis.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Maybe Compress from Apache Commons could help you.
jar is a disguised unzipper. Is that usable?