1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.utils;
\r
14 import java.io.BufferedReader;
\r
15 import java.io.Closeable;
\r
16 import java.io.File;
\r
17 import java.io.FileFilter;
\r
18 import java.io.FileInputStream;
\r
19 import java.io.FileNotFoundException;
\r
20 import java.io.FileOutputStream;
\r
21 import java.io.IOException;
\r
22 import java.io.InputStream;
\r
23 import java.io.InputStreamReader;
\r
24 import java.io.OutputStream;
\r
25 import java.io.RandomAccessFile;
\r
26 import java.io.UnsupportedEncodingException;
\r
27 import java.net.URI;
\r
28 import java.net.URL;
\r
29 import java.nio.channels.FileChannel;
\r
30 import java.nio.charset.Charset;
\r
31 import java.nio.file.FileVisitResult;
\r
32 import java.nio.file.Files;
\r
33 import java.nio.file.Path;
\r
34 import java.nio.file.SimpleFileVisitor;
\r
35 import java.nio.file.StandardCopyOption;
\r
36 import java.nio.file.attribute.BasicFileAttributes;
\r
37 import java.util.ArrayList;
\r
38 import java.util.Arrays;
\r
39 import java.util.Deque;
\r
40 import java.util.LinkedList;
\r
41 import java.util.Random;
\r
42 import java.util.zip.DataFormatException;
\r
43 import java.util.zip.Deflater;
\r
44 import java.util.zip.Inflater;
\r
45 import java.util.zip.ZipEntry;
\r
46 import java.util.zip.ZipException;
\r
47 import java.util.zip.ZipInputStream;
\r
48 import java.util.zip.ZipOutputStream;
\r
50 import org.simantics.databoard.Bindings;
\r
51 import org.simantics.databoard.adapter.AdaptException;
\r
52 import org.simantics.databoard.adapter.Adapter;
\r
53 import org.simantics.databoard.adapter.AdapterConstructionException;
\r
54 import org.simantics.databoard.binding.Binding;
\r
55 import org.simantics.databoard.type.Datatype;
\r
56 import org.simantics.utils.bytes.LEInt;
\r
57 import org.simantics.utils.strings.FileNameUtils;
\r
58 import org.slf4j.Logger;
\r
59 import org.slf4j.LoggerFactory;
\r
62 * Utilities for common file operations.
\r
64 * see StreamUtil in databoard for Input/OutputStream reading/writing utils
\r
65 * @see FileNameUtils for more utils
\r
67 * @author Toni Kalajainen
\r
68 * @author Tuukka Lehtonen
\r
70 public class FileUtils {
\r
72 private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
\r
75 * Create escaped filename
\r
77 * @param name any string
\r
78 * @return file compatible string
\r
80 public static String escapeFileName(String name) {
\r
82 return java.net.URLEncoder.encode(name, "UTF-8");
\r
83 } catch (UnsupportedEncodingException e) {
\r
85 throw new RuntimeException(e);
\r
90 * Unescape filename into string
\r
93 * @return any string
\r
95 public static String unescapeFileName(String filename) {
\r
97 return java.net.URLDecoder.decode(filename, "UTF-8");
\r
98 } catch (UnsupportedEncodingException e) {
\r
100 throw new RuntimeException(e);
\r
104 public static File ensureParentDirectoryExists(String path) throws IOException {
\r
105 return ensureParentDirectoryExists(new File(path));
\r
109 * Ensures the parent directory pointed by the specified file path exists as a
\r
112 * @param path the directory whose existence is to be ensured
\r
113 * @return the requested directory
\r
114 * @throws IOException if the specified directory cannot be created or
\r
115 * already exists as a file
\r
117 public static File ensureParentDirectoryExists(File path) throws IOException {
\r
118 return ensureDirectoryExists(path.getParentFile());
\r
122 public static File ensureDirectoryExists(String path) throws IOException {
\r
123 return ensureDirectoryExists(new File(path));
\r
127 * Ensures the directory pointed by the specified file path exists as a
\r
130 * @param path the directory whose existence is to be ensured
\r
131 * @return the requested directory
\r
132 * @throws IOException if the specified directory cannot be created or
\r
133 * already exists as a file
\r
135 public static File ensureDirectoryExists(File path) throws IOException {
\r
136 if (path.isDirectory())
\r
137 // Already exists, everything OK.
\r
141 // Path is not a directory but it exists, fail!
\r
142 throw new IOException("file '" + path + "', already exists but it is not a directory");
\r
145 if (!path.exists())
\r
146 // Path is not a directory but it exists, fail!
\r
147 throw new IOException("could not create directory '" + path + "' for an unknown reason");
\r
149 // Directory created OK.
\r
154 * Copies the contents of a source file to the destination file.
\r
156 * @param sourceFile the source file descriptor
\r
157 * @param destFile the destination file descriptor
\r
158 * @throws IOException when anything IO-related goes wrong during the copy
\r
160 public static void copyFile(File sourceFile, File destFile) throws IOException {
\r
161 if (!destFile.exists()) {
\r
162 destFile.createNewFile();
\r
165 FileInputStream fis = null;
\r
166 FileOutputStream fos = null;
\r
168 fis = new FileInputStream(sourceFile);
\r
169 fos = new FileOutputStream(destFile);
\r
170 FileChannel source = fis.getChannel();
\r
171 FileChannel destination = fos.getChannel();
\r
174 long size = source.size();
\r
175 while (count < size) {
\r
176 count += destination.transferFrom(source, count, size - count);
\r
180 uncheckedClose(fis);
\r
183 uncheckedClose(fos);
\r
189 * Copy file or dir recursively.
\r
193 * @throws IOException
\r
195 public static void copy(File src, File dst) throws IOException
\r
197 if (src.isDirectory()) {
\r
198 if(!dst.exists()) dst.mkdir();
\r
200 for (String file : src.list()) {
\r
201 File srcFile = new File(src, file);
\r
202 File dstFile = new File(dst, file);
\r
203 copy(srcFile,dstFile);
\r
206 copyFile(src, dst);
\r
211 // public static File createTempFileFromResource(URL sourceUrl) throws IOException {
\r
212 // sourceUrl = FileLocator.resolve(sourceUrl);
\r
213 // File sourceFile;
\r
215 // if (sourceUrl.getProtocol().equalsIgnoreCase("file"))
\r
216 // sourceFile = new File(sourceUrl.getPath());
\r
218 // sourceFile = new File(sourceUrl.toURI());
\r
219 // } catch (URISyntaxException e) {
\r
220 // throw new RuntimeException(e);
\r
223 // File tempFile = File.createTempFile("tmp", ".tmp");
\r
224 // FileUtils.copyFile(sourceFile, tempFile);
\r
225 // return tempFile;
\r
229 * Reads entire binary file
\r
231 * @return contents of binary file
\r
232 * @throws IOException on i/o problems
\r
234 public static byte[] readFile(File file)
\r
237 try (FileInputStream fis = new FileInputStream(file)) {
\r
238 long size = file.length();
\r
239 if (size>Integer.MAX_VALUE)
\r
240 throw new IOException("File too big");
\r
241 int len = (int) size;
\r
242 byte data [] = new byte[len];
\r
246 int read = fis.read(data, pos, len-pos);
\r
254 * Creates and writes a binary file
\r
257 * @throws IOException on i/o problems
\r
259 public static void writeFile(File file, byte[] data)
\r
262 // file.createNewFile();
\r
263 // file.setWritable(true);
\r
264 try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
\r
265 raf.setLength(data.length);
\r
273 * Fetch the entire contents of the input stream text file, and return it in
\r
274 * a String. This style of implementation does not throw Exceptions to the
\r
277 * @param stream the stream to completely read in
\r
279 public static String getContents(InputStream stream) throws IOException {
\r
280 return getContents(stream, Charset.defaultCharset());
\r
284 * Fetch the entire contents of the input stream text file, and return it in
\r
285 * a String. This style of implementation does not throw Exceptions to the
\r
288 * @param stream the stream to completely read in
\r
290 public static String getContents(InputStream stream, Charset charset, String lineSeparator) throws IOException {
\r
291 StringBuilder contents = new StringBuilder();
\r
292 BufferedReader input = null;
\r
294 input = new BufferedReader(new InputStreamReader(stream, charset));
\r
296 String line = null;
\r
297 while ((line = input.readLine()) != null) {
\r
298 contents.append(line);
\r
299 contents.append(lineSeparator);
\r
303 if (input != null) {
\r
304 // flush and close both "input" and its underlying
\r
308 } catch (IOException ex) {
\r
309 ex.printStackTrace();
\r
312 return contents.toString();
\r
315 public static String getContents(File f) throws IOException {
\r
316 return getContents(f, Charset.defaultCharset());
\r
319 public static String getContents(File f, Charset charset) throws IOException {
\r
320 return getContents(new FileInputStream(f), charset);
\r
323 public static String getContents(InputStream stream, Charset charset) throws IOException {
\r
324 return getContents(stream, charset, System.getProperty("line.separator"));
\r
327 public static String getContents(InputStream stream, String lineSeparator) throws IOException {
\r
328 return getContents(stream, Charset.defaultCharset(), lineSeparator);
\r
332 * Fetch the entire contents of a text file, and return it in a String. This
\r
333 * style of implementation does not throw Exceptions to the caller.
\r
335 * @param sourcePath is a file which already exists and can be read.
\r
337 public static String getContents(String sourcePath) throws IOException {
\r
338 return getContents(sourcePath, Charset.defaultCharset(), System.getProperty("line.separator"));
\r
341 public static String getContents(String sourcePath, String lineSeparator) throws IOException {
\r
342 return getContents(sourcePath, Charset.defaultCharset(), lineSeparator);
\r
345 public static String getContents(String sourcePath, Charset charset) throws IOException {
\r
346 return getContents(sourcePath, charset, System.getProperty("line.separator"));
\r
350 * Fetch the entire contents of a text file, and return it in a String. This
\r
351 * style of implementation does not throw Exceptions to the caller.
\r
353 * @param sourcePath is a file which already exists and can be read.
\r
355 public static String getContents(String sourcePath, Charset charset, String lineSeparator) throws IOException {
\r
356 FileInputStream input = null;
\r
358 input = new FileInputStream(sourcePath);
\r
359 return getContents(input, charset, lineSeparator);
\r
361 uncheckedClose(input);
\r
366 * Get the contents of a file which is located inside a given bundle.
\r
367 * This works regardless of whether the bundle is jarred or not.
\r
369 * @param URL the resource to read in
\r
370 * @return the contents of the resource
\r
371 * @throws IOException if the file is not found or other io errors occur
\r
373 public static String getContents(URL url) throws IOException {
\r
375 throw new IllegalArgumentException("null URL");
\r
376 InputStream input = null;
\r
378 input = url.openStream();
\r
379 return FileUtils.getContents(input);
\r
381 uncheckedClose(input);
\r
386 * Read a binary file into a java instance. Binary file is a variant,
\r
387 * there is a filetype in the header of the file.
\r
388 * If requested binding is not the exact binding of the file, an adapter is tried.
\r
391 * @param binding content binding
\r
393 * @throws IOException
\r
395 public static Object readFile(InputStream stream, Binding binding) throws IOException {
\r
396 Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
\r
397 Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( stream );
\r
399 if (type.equals(binding.type())) {
\r
400 return Bindings.getSerializerUnchecked( binding ).deserialize(stream);
\r
403 Binding fileContentBinding = Bindings.getMutableBinding(type);
\r
404 Adapter adapter = Bindings.adapterFactory.getAdapter(fileContentBinding, binding, true, false);
\r
405 Object value = Bindings.getSerializerUnchecked( fileContentBinding ).deserialize(stream);
\r
406 return adapter.adapt( value );
\r
407 } catch (AdapterConstructionException e) {
\r
408 throw new IOException(e);
\r
409 } catch (AdaptException e) {
\r
410 throw new IOException(e);
\r
416 * Deletes all files and sub-directories from the specified directory. If a
\r
417 * file is specified, only that fill will be deleted.
\r
420 * @throws IOException
\r
422 public static void deleteAll(File dir) throws IOException {
\r
423 if (dir.isFile()) {
\r
428 if (dir.isDirectory()) {
\r
429 File[] fs = dir.listFiles((FileFilter) null);
\r
433 for (File f : fs) {
\r
434 if (f.isDirectory()) {
\r
438 throw new IOException("Could not delete file: " + f.getAbsolutePath());
\r
443 if (!dir.delete()) {
\r
444 throw new IOException("Could not delete directory: " + dir.getAbsolutePath());
\r
446 } else if (dir.exists()) {
\r
447 if (!dir.delete()) {
\r
448 throw new IOException("Could not delete file: " + dir.getAbsolutePath());
\r
454 * Deletes all files and sub-directories from the specified directory. If a
\r
455 * file is specified, only that fill will be deleted.
\r
457 * If the given directory contains files listed in the filter those files are not deleted
\r
460 * directory from where to start the deletion
\r
462 * filter containing specific file paths not to delete
\r
463 * @throws IOException
\r
465 public static void deleteAllWithFilter(File dir, ArrayList<String> filter) throws IOException {
\r
466 if (dir.isFile()) {
\r
467 if (!filter.contains(dir.getAbsolutePath())) {
\r
473 if (dir.isDirectory()) {
\r
474 File[] fs = dir.listFiles((FileFilter) null);
\r
478 for (File f : fs) {
\r
479 if (f.isDirectory()) {
\r
480 deleteAllWithFilter(f, filter);
\r
482 if (!filter.contains(f.getAbsolutePath())) {
\r
484 throw new IOException("Could not delete file: " + f.getAbsolutePath());
\r
489 if (!filter.contains(dir.getAbsolutePath())) {
\r
490 if (!dir.delete()) {
\r
491 throw new IOException("Could not delete directory: " + dir.getAbsolutePath());
\r
494 } else if (dir.exists()) {
\r
495 if (filter.contains(dir.getAbsolutePath())) {
\r
496 if (!dir.delete()) {
\r
497 throw new IOException("Could not delete file: " + dir.getAbsolutePath());
\r
503 public static ArrayList<String> createFileFilter(File dir, ArrayList<String> filter) {
\r
504 if (filter == null)
\r
505 filter = new ArrayList<String>();
\r
506 if (dir.isFile()) {
\r
507 filter.add(dir.getAbsolutePath());
\r
511 if (dir.isDirectory()) {
\r
512 File[] fs = dir.listFiles((FileFilter) null);
\r
516 for (File f : fs) {
\r
517 if (f.isDirectory()) {
\r
518 createFileFilter(f, filter);
\r
520 filter.add(f.getAbsolutePath());
\r
523 filter.add(dir.getAbsolutePath());
\r
524 } else if (dir.exists()) {
\r
525 filter.add(dir.getAbsolutePath());
\r
532 * Delete a directory incl. all files and sub-directories by best effort.
\r
533 * Does not throw exceptions if deletion fails, simply tries to delete the
\r
534 * provided directory to the best of Java File API's abilities.
\r
537 * directory to delete recursively
\r
538 * @boolean <code>true</code> if all files were successfully deleted,
\r
539 * <code>false</code> if some or all failed to be deleted
\r
541 public static boolean deleteDir(File dir) {
\r
542 if (LOGGER.isDebugEnabled())
\r
543 LOGGER.debug("Deleting directory "+dir);
\r
544 boolean result = true;
\r
546 if (!dir.isDirectory()) return false;
\r
547 File[] fs = dir.listFiles();
\r
549 for (File f : fs) {
\r
550 if (f.isDirectory()) result &= deleteDir(f);
\r
551 if (f.isFile()) result &= f.delete();
\r
554 boolean ok = dir.delete();
\r
555 // if (!ok) dir.deleteOnExit();
\r
560 public static String deleteDirs(File dir) {
\r
561 if (LOGGER.isDebugEnabled())
\r
562 LOGGER.debug("Deleting directory "+dir);
\r
563 boolean result = true;
\r
565 if (!dir.isDirectory())
\r
566 return dir + " is not a directory!";
\r
567 File[] fs = dir.listFiles();
\r
569 for (File f : fs) {
\r
570 //System.out.println("file f :" + f);
\r
571 if (f.isDirectory()) {
\r
572 boolean a = deleteDir(f);
\r
576 boolean a = f.delete();
\r
582 boolean ok = dir.delete();
\r
583 // if (!ok) dir.deleteOnExit();
\r
585 return "deleteDirs succesful for " + dir + " : " + result;
\r
589 * Closes a stream and ignores any resulting exception. This is useful
\r
590 * when doing stream cleanup in a finally block where secondary exceptions
\r
591 * are not worth logging.
\r
593 public static void uncheckedClose(Closeable closeable) {
\r
595 if (closeable != null)
\r
597 } catch (IOException e) {
\r
603 * Extracts the specified source file in the specified bundle into the
\r
604 * specified local directory.
\r
606 * @param url the source URL to stream the resource from
\r
607 * @param targetFile the target file to write the resource to
\r
608 * @param deleteOnExit <code>true</code> to use {@link File#deleteOnExit()}
\r
609 * on the resulting file. Note that this does not guarantee that the
\r
610 * file is deleted when the JVM exits
\r
611 * @return the resulting file
\r
612 * @throws FileNotFoundException
\r
614 public static File copyResource(URL url, File targetFile, boolean deleteOnExit) throws IOException, FileNotFoundException {
\r
616 throw new IllegalArgumentException("null url");
\r
618 FileOutputStream os = null;
\r
619 InputStream is = null;
\r
621 if (targetFile.exists())
\r
622 targetFile.delete();
\r
624 is = url.openStream();
\r
626 byte [] buffer = new byte [16384];
\r
627 os = new FileOutputStream (targetFile);
\r
628 while ((read = is.read (buffer)) != -1) {
\r
629 os.write(buffer, 0, read);
\r
634 // Request removal of the extracted files on JVM exit.
\r
636 targetFile.deleteOnExit();
\r
639 FileUtils.uncheckedClose(os);
\r
640 FileUtils.uncheckedClose(is);
\r
645 * Creates the requested location under the system's temporary directories
\r
646 * for temporary data storage.
\r
648 * @param pathSegments the path segments that are appended to
\r
649 * java.io.tmpdir. The path segments musn't contain path separators.
\r
650 * @return the resulting temporary directory as a File object
\r
651 * @throws IOException if anything goes wrong
\r
653 public static File getOrCreateTemporaryDirectory(boolean requireEmptyDirectory, String... pathSegments) throws IOException {
\r
654 String separator = System.getProperty("file.separator");
\r
655 String tempDir = System.getProperty("java.io.tmpdir");
\r
656 if (tempDir == null)
\r
657 throw new IllegalStateException("'java.io.tmpdir' property is not defined, is the system TMP environment variable defined?");
\r
659 if (!hasTrailingSeparator(tempDir))
\r
660 tempDir = tempDir + separator;
\r
662 for (int i = 0; i < pathSegments.length-1; ++i) {
\r
663 if (containsSeparator(pathSegments[i]))
\r
664 throw new IllegalArgumentException("path segments contain path separators: " + Arrays.toString(pathSegments));
\r
665 tempDir = pathSegments[i] + separator;
\r
668 // Find name for an empty or non-existing temporary directory
\r
669 if (pathSegments.length > 0) {
\r
670 String lastSegment = pathSegments[pathSegments.length - 1];
\r
671 String suffix = "";
\r
673 // This loop will not exit until it succeeds or some error occurs.
\r
675 File temp = new File(tempDir + lastSegment + suffix);
\r
677 if (!temp.exists()) {
\r
678 // Found non-existent temporary directory!
\r
679 if (temp.mkdirs()) {
\r
680 // Ok, everything seems to be fine.
\r
683 // For some reason the directory could not be created, lets
\r
684 // try another name.
\r
686 // Found an existing temporary file.
\r
687 if (temp.isDirectory() && temp.canWrite()) {
\r
688 if (requireEmptyDirectory) {
\r
689 String[] files = temp.list();
\r
690 if (files != null) {
\r
691 if (files.length == 0) {
\r
692 // Ok, the directory is empty and writable.
\r
699 // Either the directory was empty or it could not be
\r
700 // checked. In any case, don't use the directory.
\r
704 // Try another directory name if no success with this one.
\r
705 suffix = Integer.toHexString(counter);
\r
709 return new File(tempDir);
\r
712 private static boolean containsSeparator(String s) {
\r
713 return s.contains("/") || s.contains("\\");
\r
716 private static boolean hasTrailingSeparator(String s) {
\r
717 return s.endsWith("/") || s.endsWith("\\");
\r
721 * Very simple compression using ZLib
\r
722 * @param input the uncompressed data
\r
723 * @return the compressed data
\r
725 public static byte[] deflate(byte[] input) {
\r
726 // Compress the bytes
\r
727 Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION);
\r
728 compresser.setInput(input);
\r
729 compresser.finish();
\r
731 int bufferSize = input.length<16 ? 16 : input.length;
\r
732 byte buffer[] = new byte[bufferSize];
\r
735 int compressedDataLength = compresser.deflate(buffer, bufferPos, buffer.length-bufferPos);
\r
736 bufferPos += compressedDataLength;
\r
737 if (!compresser.finished())
\r
738 buffer = Arrays.copyOf(buffer, buffer.length + bufferSize);
\r
739 } while (!compresser.finished());
\r
741 byte[] result = new byte[bufferPos+4];
\r
742 System.arraycopy(buffer, 0, result, 4, bufferPos);
\r
743 byte sizeData[] = LEInt.toBytes(input.length);
\r
744 System.arraycopy(sizeData, 0, result, 0, 4);
\r
749 * Very simple decompression using ZLib.
\r
750 * @param input the compressed input
\r
751 * @return the uncompressed data
\r
752 * @throws DataFormatException
\r
754 public static byte[] inflate(byte[] input) throws DataFormatException {
\r
755 // Decompress the bytes
\r
756 int inflatedSize = LEInt.toInt(input);
\r
757 Inflater decompresser = new Inflater();
\r
758 decompresser.setInput(input, 4, input.length - 4);
\r
759 byte[] result = new byte[inflatedSize];
\r
760 int resultLength = decompresser.inflate(result);
\r
761 assert(resultLength == inflatedSize);
\r
762 decompresser.end();
\r
767 public static boolean isValidFileName(String name) {
\r
768 File f = new File(name) ;
\r
771 boolean ok = f.createNewFile();
\r
775 } catch (IOException ioe) {
\r
783 * Create a temporary directory
\r
785 * @return temporary directory
\r
787 public static File createTmpDir()
\r
789 String tmp = System.getenv("tmp");
\r
790 if (tmp==null) tmp = "c:/temp";
\r
791 Random r = new Random();
\r
792 String randomName = "simantics-tmp-"+(r.nextInt(10000)+10000);
\r
793 File tmpDir = new File(tmp+"/"+randomName);
\r
794 tmpDir.deleteOnExit();
\r
795 Boolean ok = tmpDir.mkdirs();
\r
796 if (!ok) throw new RuntimeException("tmp dir "+tmpDir+" was not created");
\r
800 public static void compressZip(String sourcePath, String zipDir) throws IOException {
\r
801 if (LOGGER.isDebugEnabled())
\r
802 LOGGER.debug("Compressing file " + sourcePath + " to zip " + zipDir + ".");
\r
804 File filesource = new File(sourcePath);
\r
805 URI base = filesource.toURI();
\r
806 Deque<File> queue = new LinkedList<File>();
\r
807 queue.push(filesource);
\r
808 try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipDir))) {
\r
809 while (!queue.isEmpty()) {
\r
810 filesource = queue.pop();
\r
811 for (File child : filesource.listFiles()) {
\r
812 String name = base.relativize(child.toURI()).getPath();
\r
813 if (child.isDirectory()) {
\r
815 name = name.endsWith("/") ? name : name + "/";
\r
816 zout.putNextEntry(new ZipEntry(name));
\r
818 zout.putNextEntry(new ZipEntry(name));
\r
825 LOGGER.debug("Filecompression done.");
\r
829 private static void copy(File file, ZipOutputStream zout) throws IOException {
\r
830 try (InputStream in = new FileInputStream(file)) {
\r
836 * Extract a zip file into a directory
\r
840 * @throws IOException
\r
842 public static void extractZip(File zipFile, File dst) throws IOException {
\r
843 if (LOGGER.isDebugEnabled())
\r
844 LOGGER.debug("Extracting zip "+zipFile);
\r
845 try (FileInputStream fis = new FileInputStream(zipFile)) {
\r
846 extractZip(fis, dst);
\r
851 * Extract a zip file into a directory
\r
854 * @param dst directory
\r
855 * @throws IOException
\r
857 public static void extractZip(InputStream zipInput, File dst) throws IOException {
\r
858 byte[] buf = new byte[8192];
\r
859 ZipInputStream zis = new ZipInputStream(zipInput);
\r
862 entry = zis.getNextEntry();
\r
863 while (entry != null) {
\r
864 // for each entry to be extracted
\r
865 String name = entry.getName();
\r
866 if (LOGGER.isDebugEnabled())
\r
867 LOGGER.debug("Extracting "+name);
\r
868 File file = new File(dst, name);
\r
870 if (entry.isDirectory())
\r
872 if ( !file.exists() ) file.mkdirs();
\r
874 File parent = file.getParentFile();
\r
875 if (!parent.exists()) parent.mkdirs();
\r
876 if (!file.exists()) file.createNewFile();
\r
878 FileOutputStream fileoutputstream = new FileOutputStream(file);
\r
881 while ((n = zis.read(buf, 0, buf.length)) > -1)
\r
882 fileoutputstream.write(buf, 0, n);
\r
883 } catch (ZipException e) {
\r
884 throw new IOException("Failed to extract '" + name + "'.", e);
\r
886 fileoutputstream.close();
\r
891 entry = zis.getNextEntry();
\r
897 // Test inflate & deflate
\r
898 public static void main(String[] args) {
\r
900 // Test compression
\r
901 String str = "abcdefghijklmnopqrstuvwxyz";
\r
902 byte data[] = str.getBytes();
\r
903 System.out.println("Data:\t"+data.length);
\r
904 byte deflated[] = deflate(data);
\r
905 System.out.println("Deflated:\t"+deflated.length);
\r
906 byte inflated[] = inflate(deflated);
\r
907 System.out.println("Inflated:\t"+inflated.length);
\r
908 String str2 = new String(inflated);
\r
909 System.out.println("Strings are equal: "+str.endsWith(str2));
\r
910 } catch (DataFormatException e) {
\r
911 e.printStackTrace();
\r
915 public static File[] listFilesByExtension(File directory, final String extension) {
\r
916 return directory.listFiles(new ExtensionFilter(extension));
\r
920 * Copy the content of the input stream into the output stream, using a temporary
\r
921 * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.
\r
923 * @param in The input stream to copy from.
\r
924 * @param out The output stream to copy to.
\r
926 * @throws IOException If any error occurs during the copy.
\r
928 private static final int IO_BUFFER_SIZE = 64 * 1024;
\r
930 public static void copy(InputStream in, OutputStream out) throws IOException {
\r
931 byte[] b = new byte[IO_BUFFER_SIZE];
\r
937 out.write(b, 0, read);
\r
944 * @param maxBytesToCopy the maximum amount of bytes to copy
\r
945 * @return the amount of bytes copied
\r
946 * @throws IOException
\r
948 public static long copy(InputStream in, OutputStream out, long maxBytesToCopy) throws IOException {
\r
949 byte[] b = new byte[IO_BUFFER_SIZE];
\r
951 while (read < maxBytesToCopy) {
\r
952 int l = (int) Math.min((long) IO_BUFFER_SIZE, maxBytesToCopy-read);
\r
953 int r = in.read(b, 0, l);
\r
956 out.write(b, 0, r);
\r
962 public static void delete(Path databaseLocation) throws IOException {
\r
963 Files.walkFileTree(databaseLocation, new DeleteDirectoriesVisitor());
\r
966 public static void copy(Path from, Path to) throws IOException {
\r
967 Files.walkFileTree(from, new CopyDirectoriesVisitor(from, to));
\r
970 public static class DeleteDirectoriesVisitor extends SimpleFileVisitor<Path> {
\r
973 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
\r
974 Files.delete(file);
\r
975 if (Files.exists(file))
\r
976 throw new IOException("Could not delete file " + file.toAbsolutePath().toString());
\r
977 return FileVisitResult.CONTINUE;
\r
981 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
\r
985 if (Files.exists(dir))
\r
986 throw new IOException("Could not delete file " + dir.toAbsolutePath().toString());
\r
987 return FileVisitResult.CONTINUE;
\r
991 public static class CopyDirectoriesVisitor extends SimpleFileVisitor<Path> {
\r
993 private final Path fromPath;
\r
994 private final Path toPath;
\r
996 public CopyDirectoriesVisitor(Path fromPath, Path toPath) {
\r
997 this.fromPath = fromPath;
\r
998 this.toPath = toPath;
\r
1002 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
\r
1003 Path targetPath = toPath.resolve(fromPath.relativize(dir));
\r
1004 if(!Files.exists(targetPath)){
\r
1005 Files.createDirectory(targetPath);
\r
1007 return FileVisitResult.CONTINUE;
\r
1011 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
\r
1012 Files.copy(file, toPath.resolve(fromPath.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
\r
1013 return FileVisitResult.CONTINUE;
\r