This question already has answers here:
Recommended way to save uploaded files in a servlet application
(2 answers)
Closed 6 years ago.
$uploads_dir = '/uploads';
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
// basename() may prevent filesystem traversal attacks;
// further validation/sanitation of the filename may be appropriate
$name = basename($_FILES["pictures"]["name"][$key]);
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
}
This is how to upload images using PHP. Is there same function for JAVA. I want to upload image and save it in folder but using JAVA.
The action should happened on form submit.
No servlet for this upload
This might help: copies all files from one folder to another :
/**
* Copy files from one directory to another.
* #param sourceFile
* #param destFile
* #throws IOException
*/
public static void copyAllDirFiles(File fromDir, File toDir)
throws IOException {
//check if source is a directory
if (!fromDir.isDirectory()) {
throw new IOException(fromDir + " directory not found.");
}
//if destination does not exit, create it
if (!toDir.exists()) {
toDir.mkdir();
}
//get files from source
File[] files = fromDir.listFiles();
for (File file : files) {
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(toDir + "/"
+ file.getName());
// Copy the bits from input stream to output stream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
Related
I am trying to put files from a folder inside a zip file in the following structure:
Folder structure:
myFolder
|-file1.txt
|-file2.txt
|-folder172
|-file817.txt
|-file818.txt
...
Supposed structure inside ZipFile:
file1.txt
file2.txt
folder172
|-file817.txt
|-file818.txt
This is my code:
public static void writeZip(String path) throws IOException{
FileOutputStream fos = new FileOutputStream(path+File.separator+"atest.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
try {
Files.walk(Paths.get(path)).filter(Files::isRegularFile).forEach((string) -> addToZipFile(string.toString(),zos));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
zos.close();
fos.close();
}
public static void addToZipFile(String fileName, ZipOutputStream zos) throws IOException {
System.out.println("Writing '" + fileName + "' to zip file");
File file = new File(fileName);
FileInputStream fis = null;
fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
}
The problem is now, when i call writeZip("/home/arthur/.grutil/");, i get the following structure in the zip-file:
home
|-arthur
|-.grutil
|-file1.txt
|-file2.txt
|-folder172
|-file817.txt
|-file818.txt
...
How do i need to change my code to get the supposed structure (as described above) and not the structure with the full path '/home/arthur/.grutil/ ...'?
Whilst this can be done with the ancient ZipOutputStream I would recommend against it.
It is much more intuitive to think about a Zip archive as a compressed filesystem inside a file, than a stream of bytes. For this reason, Java provides the ZipFileSystem.
So all you need to do is open the Zip as a FileSystem and then manually copy files across.
There are a couple of gotchas:
You need to only copy files, directories need to be created.
The NIO API does not support operations such as relativize across different filesystems (reasons should be obvious) so this you need to do yourself.
Here are a couple of simple methods that will do exactly that:
/**
* This creates a Zip file at the location specified by zip
* containing the full directory tree rooted at contents
*
* #param zip the zip file, this must not exist
* #param contents the root of the directory tree to copy
* #throws IOException, specific exceptions thrown for specific errors
*/
public static void createZip(final Path zip, final Path contents) throws IOException {
if (Files.exists(zip)) {
throw new FileAlreadyExistsException(zip.toString());
}
if (!Files.exists(contents)) {
throw new FileNotFoundException("The location to zip must exist");
}
final Map<String, String> env = new HashMap<>();
//creates a new Zip file rather than attempting to read an existing one
env.put("create", "true");
// locate file system by using the syntax
// defined in java.net.JarURLConnection
final URI uri = URI.create("jar:file:/" + zip.toString().replace("\\", "/"));
try (final FileSystem zipFileSystem = FileSystems.newFileSystem(uri, env);
final Stream<Path> files = Files.walk(contents)) {
final Path root = zipFileSystem.getPath("/");
files.forEach(file -> {
try {
copyToZip(root, contents, file);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
/**
* Copy a specific file/folder to the zip archive
* If the file is a folder, create the folder. Otherwise copy the file
*
* #param root the root of the zip archive
* #param contents the root of the directory tree being copied, for relativization
* #param file the specific file/folder to copy
*/
private static void copyToZip(final Path root, final Path contents, final Path file) throws IOException {
final Path to = root.resolve(contents.relativize(file).toString());
if (Files.isDirectory(file)) {
Files.createDirectories(to);
} else {
Files.copy(file, to);
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to make a specified directory to an archived file and store in according to my desired location?
is it possible to create?
Please share the information if you have.
my code:
File input = new File("sample.tar.gz");
TFile sourceFile = new TFile(input);
TFile targetFile = new TFile(File.createTempFile("sample", ".zip"));
try
{
TFile.cp_rp(sourceFile, targetFile, TArchiveDetector.NULL);
}
finally
{
TFile.umount(targetFile);
}
try following:
import java.io.*;
import java.util.zip.*;
/**
* This class defines two static methods for gzipping files and zipping
* directories. It also defines a demonstration program as a nested class.
**/
public class Compress {
/** Gzip the contents of the from file and save in the to file. */
public static void gzipFile(String from, String to) throws IOException {
// Create stream to read from the from file
FileInputStream in = new FileInputStream(from);
// Create stream to compress data and write it to the to file.
GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(to));
// Copy bytes from one stream to the other
byte[] buffer = new byte[4096];
int bytes_read;
while((bytes_read = in.read(buffer)) != -1)
out.write(buffer, 0, bytes_read);
// And close the streams
in.close();
out.close();
}
/** Zip the contents of the directory, and save it in the zipfile */
public static void zipDirectory(String dir, String zipfile)
throws IOException, IllegalArgumentException {
// Check that the directory is a directory, and get its contents
File d = new File(dir);
if (!d.isDirectory())
throw new IllegalArgumentException("Compress: not a directory: " + dir);
String[] entries = d.list();
byte[] buffer = new byte[4096]; // Create a buffer for copying
int bytes_read;
// Create a stream to compress data and write it to the zipfile
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile));
// Loop through all entries in the directory
for(int i = 0; i < entries.length; i++) {
File f = new File(d, entries[i]);
if (f.isDirectory()) continue; // Don't zip sub-directories
FileInputStream in = new FileInputStream(f); // Stream to read file
ZipEntry entry = new ZipEntry(f.getPath()); // Make a ZipEntry
out.putNextEntry(entry); // Store entry in zipfile
while((bytes_read = in.read(buffer)) != -1) // Copy bytes to zipfile
out.write(buffer, 0, bytes_read);
in.close(); // Close input stream
}
// When we're done with the whole loop, close the output stream
out.close();
}
/**
* This nested class is a test program that demonstrates the use of the
* static methods defined above.
**/
public static class Test {
/**
* Compress a specified file or directory. If no destination name is
* specified, append .gz to a file name or .zip to a directory name
**/
public static void main(String args[]) throws IOException {
if ((args.length != 1) && (args.length != 2)) { // check arguments
System.err.println("Usage: java Compress$Test <from> [<to>]");
System.exit(0);
}
String from = args[0], to;
File f = new File(from);
boolean directory = f.isDirectory(); // Is it a file or directory?
if (args.length == 2) to = args[1];
else { // If destination not specified
if (directory) to = from + ".zip"; // use a .zip suffix
else to = from + ".gz"; // or a .gz suffix
}
if ((new File(to)).exists()) { // Make sure not to overwrite anything
System.err.println("Compress: won't overwrite existing file: " + to);
System.exit(0);
}
// Finally, call one of the methods defined above to do the work.
if (directory) Compress.zipDirectory(from, to);
else Compress.gzipFile(from, to);
}
}
}
This question already has answers here:
How to create Uncompressed Zip archive in Java
(4 answers)
Closed 6 years ago.
I'm trying to compress directory content into zip archive using java.
Everything is fine, but I just want to clarify some facts.
Here is the code which I use to compress files:
public void pack(#Nonnull String archiveName, #Nonnull File outputDir, #Nonnull File targetDir) {
File zipFile = new File(outputDir, "out.zip");
ZipOutputStream zipOutputStream = null;
OutputStream outputStream;
try {
// create stream for writing zip archive
outputStream = new FileOutputStream(zipFile);
zipOutputStream = new ZipOutputStream(outputStream);
// write files recursively
writeFiles(zipOutputStream, targetDir.listFiles(), "");
} catch (IOException e) {
LOGGER.error("IO exception while packing files to archive", e);
} finally {
// close output streams
if (zipOutputStream != null) {
try {
zipOutputStream.close();
} catch (IOException e) {
LOGGER.error("Unable to close zip output stream", e);
}
}
}
}
/**
* Writes specified files and their children (in case of directories) to archive
*
* #param zipOutputStream archive output stream
* #param files which should be added to archive
* #param path path relative of root of archive where files should be placed
*/
private void writeFiles(#Nonnull ZipOutputStream zipOutputStream, #Nullable File[] files, #Nonnull String path) throws IOException {
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
// recursively add files in this directory
String fullDirectoryName = path + file.getName() + "/";
File[] childFiles = file.listFiles();
if (childFiles != null && childFiles.length > 0) {
// write child files to archive. current directory will be created automatically
writeFiles(zipOutputStream, childFiles, fullDirectoryName);
} else {
// empty directory. write directory itself to archive
ZipEntry entry = new ZipEntry(fullDirectoryName);
zipOutputStream.putNextEntry(entry);
zipOutputStream.closeEntry();
}
} else {
// put file in archive
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
zipOutputStream.putNextEntry(new ZipEntry(path + file.getName()));
ByteStreams.copy(bufferedInputStream, zipOutputStream);
zipOutputStream.closeEntry();
bufferedInputStream.close();
}
}
}
Now there are the questions:
Is it correct that by default (and in my case too) I will get already compressed archive (using Deflate method)?
How to get uncompressed archive:
If I set method zipOutputStream.setMethod(ZipOutputStream.STORED) I have to provide size, compressed size (is it will be equal to size?) and crc, otherwise I will get exceptions
If I don't want to calculate size and crc by myself I can use DEFLATE method with zero level:
zipOutputStream.setMethod(ZipOutputStream.DEFLATED);
zipOutputStream.setLevel(ZipOutputStream.STORED);So, is it correct that in this case I get not compressed archive at all?
Is there more convenient-obvious method to creating not-compressed archives?
Rather than re-invent the wheel I'd seriously consider using an existing library for this, such as Apache Ant. The basic idiom for creating a zip file is:
Project p = new Project();
p.init();
Zip zip = new Zip();
zip.setProject(p);
zip.setDestFile(new File(outputDir, "out.zip"));
FileSet fs = new FileSet();
fs.setProject(p);
fs.setDirectory(targetDir);
zip.addFileset(fs);
zip.perform();
By default you will get a compressed archive. For an uncompressed zip all you need to add is
zip.setCompress(false);
after the setDestFile (in fact anywhere before the perform).
I want to copy a file from a jar. The file that I am copying is going to be copied outside the working directory. I have done some tests and all methods I try end up with 0 byte files.
EDIT: I want the copying of the file to be done via a program, not manually.
First of all I want to say that some answers posted before are entirely correct, but I want to give mine, since sometimes we can't use open source libraries under the GPL, or because we are too lazy to download the jar XD or what ever your reason is here is a standalone solution.
The function below copy the resource beside the Jar file:
/**
* Export a resource embedded into a Jar file to the local file path.
*
* #param resourceName ie.: "/SmartLibrary.dll"
* #return The path to the exported resource
* #throws Exception
*/
static public String ExportResource(String resourceName) throws Exception {
InputStream stream = null;
OutputStream resStreamOut = null;
String jarFolder;
try {
stream = ExecutingClass.class.getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree
if(stream == null) {
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
}
int readBytes;
byte[] buffer = new byte[4096];
jarFolder = new File(ExecutingClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile().getPath().replace('\\', '/');
resStreamOut = new FileOutputStream(jarFolder + resourceName);
while ((readBytes = stream.read(buffer)) > 0) {
resStreamOut.write(buffer, 0, readBytes);
}
} catch (Exception ex) {
throw ex;
} finally {
stream.close();
resStreamOut.close();
}
return jarFolder + resourceName;
}
Just change ExecutingClass to the name of your class, and call it like this:
String fullPath = ExportResource("/myresource.ext");
Edit for Java 7+ (for your convenience)
As answered by GOXR3PLUS and noted by Andy Thomas you can achieve this with:
Files.copy( InputStream in, Path target, CopyOption... options)
See GOXR3PLUS answer for more details
Given your comment about 0-byte files, I have to assume you're trying to do this programmatically, and, given your tags, that you're doing it in Java. If that's true, then just use Class.getResource() to get a URL pointing to the file in your JAR, then Apache Commons IO FileUtils.copyURLToFile() to copy it out to the file system. E.g.:
URL inputUrl = getClass().getResource("/absolute/path/of/source/in/jar/file");
File dest = new File("/path/to/destination/file");
FileUtils.copyURLToFile(inputUrl, dest);
Most likely, the problem with whatever code you have now is that you're (correctly) using a buffered output stream to write to the file but (incorrectly) failing to close it.
Oh, and you should edit your question to clarify exactly how you want to do this (programmatically, not, language, ...)
Faster way to do it with Java 7+ , plus code to get the current directory:
/**
* Copy a file from source to destination.
*
* #param source
* the source
* #param destination
* the destination
* #return True if succeeded , False if not
*/
public static boolean copy(InputStream source , String destination) {
boolean succeess = true;
System.out.println("Copying ->" + source + "\n\tto ->" + destination);
try {
Files.copy(source, Paths.get(destination), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
logger.log(Level.WARNING, "", ex);
succeess = false;
}
return succeess;
}
Testing it (icon.png is an image inside the package image of the application):
copy(getClass().getResourceAsStream("/image/icon.png"),getBasePathForClass(Main.class)+"icon.png");
About the line of code (getBasePathForClass(Main.class)): -> check the answer i have added here :) -> Getting the Current Working Directory in Java
Java 8 (actually FileSystem is there since 1.7) comes with some cool new classes/methods to deal with this. As somebody already mentioned that JAR is basically ZIP file, you could use
final URI jarFileUril = URI.create("jar:file:" + file.toURI().getPath());
final FileSystem fs = FileSystems.newFileSystem(jarFileUri, env);
(See Zip File)
Then you can use one of the convenient methods like:
fs.getPath("filename");
Then you can use Files class
try (final Stream<Path> sources = Files.walk(from)) {
sources.forEach(src -> {
final Path dest = to.resolve(from.relativize(src).toString());
try {
if (Files.isDirectory(from)) {
if (Files.notExists(to)) {
log.trace("Creating directory {}", to);
Files.createDirectories(to);
}
} else {
log.trace("Extracting file {} to {}", from, to);
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException("Failed to unzip file.", e);
}
});
}
Note: I tried that to unpack JAR files for testing
Robust solution:
public static void copyResource(String res, String dest, Class c) throws IOException {
InputStream src = c.getResourceAsStream(res);
Files.copy(src, Paths.get(dest), StandardCopyOption.REPLACE_EXISTING);
}
You can use it like this:
File tempFileGdalZip = File.createTempFile("temp_gdal", ".zip");
copyResource("/gdal.zip", tempFileGdalZip.getAbsolutePath(), this.getClass());
Use the JarInputStream class:
// assuming you already have an InputStream to the jar file..
JarInputStream jis = new JarInputStream( is );
// get the first entry
JarEntry entry = jis.getNextEntry();
// we will loop through all the entries in the jar file
while ( entry != null ) {
// test the entry.getName() against whatever you are looking for, etc
if ( matches ) {
// read from the JarInputStream until the read method returns -1
// ...
// do what ever you want with the read output
// ...
// if you only care about one file, break here
}
// get the next entry
entry = jis.getNextEntry();
}
jis.close();
See also: JarEntry
To copy a file from your jar, to the outside, you need to use the following approach:
Get a InputStream to a the file inside your jar file using getResourceAsStream()
We open our target file using a FileOutputStream
We copy bytes from the input to the output stream
We close our streams to prevent resource leaks
Example code that also contains a variable to not replace the existing values:
public File saveResource(String name) throws IOException {
return saveResource(name, true);
}
public File saveResource(String name, boolean replace) throws IOException {
return saveResource(new File("."), name, replace)
}
public File saveResource(File outputDirectory, String name) throws IOException {
return saveResource(outputDirectory, name, true);
}
public File saveResource(File outputDirectory, String name, boolean replace)
throws IOException {
File out = new File(outputDirectory, name);
if (!replace && out.exists())
return out;
// Step 1:
InputStream resource = this.getClass().getResourceAsStream(name);
if (resource == null)
throw new FileNotFoundException(name + " (resource not found)");
// Step 2 and automatic step 4
try(InputStream in = resource;
OutputStream writer = new BufferedOutputStream(
new FileOutputStream(out))) {
// Step 3
byte[] buffer = new byte[1024 * 4];
int length;
while((length = in.read(buffer)) >= 0) {
writer.write(buffer, 0, length);
}
}
return out;
}
A jar is just a zip file. Unzip it (using whatever method you're comfortable with) and copy the file normally.
${JAVA_HOME}/bin/jar -cvf /path/to.jar
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.