Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java127
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOVisitor.java22
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/NIOUtil.java136
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TMPUtil.java (renamed from plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TempUtil.java)4
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ZIPUtil.java303
5 files changed, 590 insertions, 2 deletions
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
index fc6e517f96..3ed92ac5ea 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
@@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
/**
* @author Eike Stepper
@@ -226,6 +228,80 @@ public final class IOUtil
}
}
+ public static List<File> listDepthFirst(File file)
+ {
+ FileCollector collector = new FileCollector();
+ visitDepthFirst(file, collector);
+ return collector.getFiles();
+ }
+
+ public static List<File> listBreadthFirst(File file)
+ {
+ FileCollector collector = new FileCollector();
+ visitBreadthFirst(file, collector);
+ return collector.getFiles();
+ }
+
+ public static void visitDepthFirst(File file, IOVisitor visitor) throws IORuntimeException
+ {
+ try
+ {
+ boolean recurse = visitor.visit(file);
+ if (recurse && file.isDirectory())
+ {
+ visitDepthFirst(file.listFiles(), visitor);
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ }
+
+ public static void visitDepthFirst(File[] files, IOVisitor visitor)
+ {
+ for (File file : files)
+ {
+ visitDepthFirst(file, visitor);
+ }
+ }
+
+ public static void visitBreadthFirst(File file, IOVisitor visitor) throws IORuntimeException
+ {
+ File[] files = { file };
+ visitBreadthFirst(files, visitor);
+ }
+
+ public static void visitBreadthFirst(File[] files, IOVisitor visitor) throws IORuntimeException
+ {
+ try
+ {
+ boolean[] recurse = new boolean[files.length];
+ for (int i = 0; i < files.length; i++)
+ {
+ File file = files[i];
+ recurse[i] = visitor.visit(file);
+ }
+
+ for (int i = 0; i < files.length; i++)
+ {
+ File file = files[i];
+ if (file.isDirectory() && recurse[i])
+ {
+ File[] children = file.listFiles();
+ for (File child : children)
+ {
+ visitBreadthFirst(child, visitor);
+ }
+ }
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ }
+
public static void safeRun(Closeable io, IORunnable runnable) throws IORuntimeException
{
try
@@ -287,4 +363,55 @@ public final class IOUtil
throw new IORuntimeException(ex);
}
}
+
+ public static boolean equals(File file1, File file2) throws IORuntimeException
+ {
+ if (file1.length() != file2.length())
+ {
+ return false;
+ }
+
+ FileInputStream stream1 = null;
+ FileInputStream stream2 = null;
+
+ try
+ {
+ stream1 = new FileInputStream(file1);
+ stream2 = new FileInputStream(file2);
+
+ return equals(stream1, stream2);
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ finally
+ {
+ closeSilent(stream1);
+ closeSilent(stream2);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class FileCollector implements IOVisitor
+ {
+ private List<File> files = new ArrayList();
+
+ public FileCollector()
+ {
+ }
+
+ public List<File> getFiles()
+ {
+ return files;
+ }
+
+ public boolean visit(File file) throws IOException
+ {
+ files.add(file);
+ return true;
+ }
+ }
}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOVisitor.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOVisitor.java
new file mode 100644
index 0000000000..3f31db5385
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOVisitor.java
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ **************************************************************************/
+package org.eclipse.net4j.util.io;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public interface IOVisitor
+{
+ public boolean visit(File file) throws IOException;
+}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/NIOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/NIOUtil.java
index 1de881a926..23167f3ea2 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/NIOUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/NIOUtil.java
@@ -27,8 +27,13 @@ public final class NIOUtil
{
}
+ /**
+ * TODO Look at {@link #copy(File, File, boolean)}
+ */
public static void copyFile(File source, File target)
{
+ // http://www.javalobby.org/java/forums/t17036.html
+ // http://java.sun.com/developer/JDCTechTips/2002/tt0507.html#tip1
FileChannel sourceChannel = null;
FileChannel targetChannel = null;
@@ -59,4 +64,135 @@ public final class NIOUtil
IOUtil.closeSilent(targetChannel);
}
}
+
+ /**
+ * Copy source file to destination. If destination is a path then source file
+ * name is appended. If destination file exists then: overwrite=true -
+ * destination file is replaced; overwite=false - exception is thrown.
+ *
+ * @param src
+ * source file
+ * @param dst
+ * destination file or path
+ * @param overwrite
+ * overwrite destination file
+ * @exception IOException
+ * I/O problem
+ * @exception IllegalArgumentException
+ * illegal argument
+ */
+ @SuppressWarnings("unused")
+ private static void copy(final File src, File dst, final boolean overwrite) throws IOException,
+ IllegalArgumentException
+ {
+ long q = System.currentTimeMillis();
+ // checks
+ if (!src.isFile() || !src.exists())
+ throw new IllegalArgumentException("Source file '" + src.getAbsolutePath() + "' not found!");
+ if (dst.exists())
+ if (dst.isDirectory()) // Directory? -> use source file name
+ dst = new File(dst, src.getName());
+ else if (dst.isFile())
+ {
+ if (!overwrite)
+ throw new IllegalArgumentException("Destination file '" + dst.getAbsolutePath() + "' already exists!");
+ }
+ else
+ throw new IllegalArgumentException("Invalid destination object '" + dst.getAbsolutePath() + "'!");
+ File dstParent = dst.getParentFile();
+ if (!dstParent.exists())
+ if (!dstParent.mkdirs())
+ throw new IOException("Failed to create directory " + dstParent.getAbsolutePath());
+ long fileSize = src.length();
+ if (fileSize > 20971520l)
+ { // for larger files (20Mb) use streams
+ FileInputStream in = new FileInputStream(src);
+ FileOutputStream out = new FileOutputStream(dst);
+ try
+ {
+ int doneCnt = -1, bufSize = 32768;
+ byte buf[] = new byte[bufSize];
+ while ((doneCnt = in.read(buf, 0, bufSize)) >= 0)
+ if (doneCnt == 0)
+ Thread.yield();
+ else
+ out.write(buf, 0, doneCnt);
+ out.flush();
+ }
+ finally
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ else
+ { // smaller files, use channels
+ FileInputStream fis = new FileInputStream(src);
+ FileOutputStream fos = new FileOutputStream(dst);
+ FileChannel in = fis.getChannel(), out = fos.getChannel();
+
+ try
+ {
+ long offs = 0, doneCnt = 0, copyCnt = Math.min(65536, fileSize);
+ do
+ {
+ doneCnt = in.transferTo(offs, copyCnt, out);
+ offs += doneCnt;
+ fileSize -= doneCnt;
+ }
+
+ while (fileSize > 0);
+ }
+ finally
+ { // cleanup
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ }
+
+ try
+ {
+ fis.close();
+ }
+ catch (IOException e)
+ {
+ }
+
+ try
+ {
+ fos.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ } // else
+
+ System.out.println(">>> " + String.valueOf(src.length() / 1024) + " Kb, "
+ + String.valueOf(System.currentTimeMillis() - q));
+ } // copy
}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TempUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TMPUtil.java
index 4f82c2a353..cc1d3317bf 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TempUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/TMPUtil.java
@@ -16,9 +16,9 @@ import java.io.IOException;
/**
* @author Eike Stepper
*/
-public final class TempUtil
+public final class TMPUtil
{
- private TempUtil()
+ private TMPUtil()
{
}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ZIPUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ZIPUtil.java
new file mode 100644
index 0000000000..fe0559f0c6
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ZIPUtil.java
@@ -0,0 +1,303 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ **************************************************************************/
+package org.eclipse.net4j.util.io;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @author Eike Stepper
+ */
+public final class ZIPUtil
+{
+ public static final int DEFALULT_BUFFER_SIZE = 4096;
+
+ private ZIPUtil()
+ {
+ }
+
+ public static void zip(File zipFile, ZipEntryHandler handler) throws IORuntimeException
+ {
+ final byte[] buffer = new byte[DEFALULT_BUFFER_SIZE];
+ final EntryContext context = new EntryContext();
+
+ FileOutputStream fos = IOUtil.openOutputStream(zipFile);
+ ZipOutputStream zos = null;
+ InputStream input = null;
+
+ try
+ {
+ zos = new ZipOutputStream(new BufferedOutputStream(fos, DEFALULT_BUFFER_SIZE));
+ for (;;)
+ {
+ handler.handleEntry(context);
+ if (context.isEmpty())
+ {
+ break;
+ }
+
+ String name = context.getName();
+ ZipEntry entry = new ZipEntry(name);
+ zos.putNextEntry(entry);
+
+ if (!context.isDirectory())
+ {
+ try
+ {
+ input = context.getInputStream();
+ IOUtil.copy(input, zos, buffer);
+ }
+ finally
+ {
+ IOUtil.closeSilent(input);
+ }
+ }
+
+ context.reset();
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ finally
+ {
+ IOUtil.closeSilent(zos);
+ IOUtil.closeSilent(fos);
+ }
+ }
+
+ public static void zip(File zipFile, File sourceFolder, boolean excludeRoot)
+ {
+ zip(zipFile, new FileSystemZipHandler(sourceFolder, excludeRoot));
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ File zipFile = new File("C:\\org.eclipse.emf.ecore_2.3.1.v200707242120.zip");
+ File targetFolder = new File("C:\\_weaver\\org.eclipse.emf.ecore_2.3.1.unzipped");
+ unzip(zipFile, targetFolder);
+
+ zip(new File("C:\\_weaver\\org.eclipse.emf.ecore_2.3.1.jar"), targetFolder, true);
+ }
+
+ public static void unzip(File zipFile, UnzipHandler handler) throws IORuntimeException
+ {
+ FileInputStream fis = IOUtil.openInputStream(zipFile);
+ ZipInputStream zis = null;
+
+ try
+ {
+ zis = new ZipInputStream(new BufferedInputStream(fis, DEFALULT_BUFFER_SIZE));
+
+ ZipEntry entry;
+ while ((entry = zis.getNextEntry()) != null)
+ {
+ if (entry.isDirectory())
+ {
+ handler.unzipDirectory(entry.getName());
+ }
+ else
+ {
+ // TODO Provide delegating InputStream that ignores close()
+ handler.unzipFile(entry.getName(), zis);
+ }
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ finally
+ {
+ IOUtil.closeSilent(zis);
+ IOUtil.closeSilent(fis);
+ }
+ }
+
+ public static void unzip(File zipFile, File targetFolder) throws IORuntimeException
+ {
+ unzip(zipFile, new FileSystemUnzipHandler(targetFolder, DEFALULT_BUFFER_SIZE));
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface ZipEntryHandler
+ {
+ public void handleEntry(EntryContext context) throws IOException;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface UnzipHandler
+ {
+ public void unzipDirectory(String name) throws IOException;
+
+ public void unzipFile(String name, InputStream zipStream) throws IOException;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class EntryContext
+ {
+ private static final String EMPTY = new String();
+
+ private String name = EMPTY;
+
+ private InputStream inputStream;
+
+ EntryContext()
+ {
+ }
+
+ void reset()
+ {
+ name = null;
+ inputStream = null;
+ }
+
+ boolean isEmpty()
+ {
+ return name == null;
+ }
+
+ boolean isDirectory()
+ {
+ return inputStream == null;
+ }
+
+ String getName()
+ {
+ if (isDirectory())
+ {
+ return name;
+ }
+
+ return name + "/";
+ }
+
+ InputStream getInputStream()
+ {
+ return inputStream;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public void setInputStream(InputStream inputStream)
+ {
+ this.inputStream = inputStream;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class FileSystemZipHandler implements ZipEntryHandler
+ {
+ private int sourceFolderLength;
+
+ private transient Iterator<File> files;
+
+ public FileSystemZipHandler(File sourceFolder, boolean excludeRoot)
+ {
+ sourceFolderLength = sourceFolder.getAbsolutePath().length();
+ files = IOUtil.listBreadthFirst(sourceFolder).iterator();
+ if (excludeRoot)
+ {
+ files.next();
+ }
+ }
+
+ public void handleEntry(EntryContext context) throws IOException
+ {
+ if (files.hasNext())
+ {
+ File file = files.next();
+ context.setName(getName(file));
+
+ if (file.isFile())
+ {
+ context.setInputStream(IOUtil.openInputStream(file));
+ }
+ }
+ }
+
+ protected String getName(File file)
+ {
+ return file.getAbsolutePath().substring(sourceFolderLength);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class FileSystemUnzipHandler implements UnzipHandler
+ {
+ private File targetFolder;
+
+ private transient byte[] buffer;
+
+ public FileSystemUnzipHandler(File targetFolder, int bufferSize)
+ {
+ this.targetFolder = targetFolder;
+ buffer = new byte[bufferSize];
+ }
+
+ public File getTargetFolder()
+ {
+ return targetFolder;
+ }
+
+ public void unzipDirectory(String name)
+ {
+ File directory = new File(targetFolder, name);
+ if (!directory.exists())
+ {
+ directory.mkdirs();
+ }
+ }
+
+ public void unzipFile(String name, InputStream zipStream)
+ {
+ File targetFile = new File(targetFolder, name);
+ if (!targetFile.getParentFile().exists())
+ {
+ targetFile.getParentFile().mkdirs();
+ }
+
+ FileOutputStream out = IOUtil.openOutputStream(targetFile);
+
+ try
+ {
+ IOUtil.copy(zipStream, out, buffer);
+ }
+ finally
+ {
+ IOUtil.closeSilent(out);
+ }
+ }
+ }
+}

Back to the top