view software/eXist/mpdl-modules/src/de/mpg/mpiwg/berlin/mpdl/util/FileUtil.java @ 0:408254cf2f1d

Erstellung
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Wed, 24 Nov 2010 17:24:23 +0100
parents
children
line wrap: on
line source

package de.mpg.mpiwg.berlin.mpdl.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import de.mpg.mpiwg.berlin.mpdl.exception.ApplicationException;

public class FileUtil {
  private static FileUtil instance;

  public static FileUtil getInstance() throws ApplicationException {
    if (instance == null) {
      instance = new FileUtil();
    }
    return instance;
  }

  public void createDirectory(String dir) {
    File destLocalDirectory = new File(dir);
    destLocalDirectory.mkdirs();
  }
 
  public void deleteDirectory(String dir) {
    File destLocalDirectory = new File(dir);
    // directory with all files and subdirectories is deleted
    deleteDirectory(destLocalDirectory);
  }
 
  /**
   *  Deletes all files and subdirectories under dir. No exception is thrown 
   *  if dir (or one of its children) does nor exist.
   *  @dir dir the directory to be deleted
   *  @return true if all deletions were successful. If a deletion fails, the method stops attempting to delete and returns false.
   */
  public boolean deleteDirectory(File dir) {
    if (dir.isDirectory()) {
      String[] children = dir.list();
      for (int i=0; i<children.length; i++) {
        boolean success = deleteDirectory(new File(dir, children[i]));
        if (!success) {
          return false;  // if one of the files or subdirectories could not be deleted return false but recursively works further
        }
      }
    }
    // The directory is now empty so delete it
    return dir.delete();
  }

  public void deleteFile(String fileName) {
    File destLocalFile = new File(fileName);
    // if destLocalFile does not exist nothing happens and no exception is thrown
    // if destLocalFile is a directory and is not empty an exception is thrown (should not happen because this method is called only by remove)
    destLocalFile.delete();  
  }
 
  /**
   * List all files in a directory
   * @param dirStr
   * @return
   */
  public File[] getFiles(String dirStr) {
    File dir = new File(dirStr);
    File[] dirFiles = dir.listFiles();
    return dirFiles;
  }
  
  /**
   * 
   * @param dirStr
   * @param filter
   * @return
   */
  public File[] getFiles(String dirStr, FilenameFilter filter) {
    File dir = new File(dirStr);
    File[] dirFiles = dir.listFiles(filter);
    return dirFiles;
  }
  
  /**
   * Write all bytes into destFile. If directory for that destFile does not exist 
   * it creates this directory including parent directories. 
   * @param bytes bytes to write
   * @param destFileName destination file name
   * @throws Exception
   */
  public void saveFile(byte[] bytes, String destFileName) throws ApplicationException {
    OutputStream out = null;
    try {
      if (bytes == null)
        return;  // do nothing
      File destFile = new File(destFileName);
      File destDir = new File(destFile.getParent()); 
      if (! destDir.exists()) {
        destDir.mkdirs();  // create the directory including parent directories which do not exist
      }
      out = new BufferedOutputStream(new FileOutputStream(destFile));
      out.write(bytes, 0, bytes.length);
      out.flush();
    } catch (FileNotFoundException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      try { 
        if (out != null)
          out.close(); 
        } catch (Exception e) { 
          // nothing: always close the stream at the end of the method
        }  
    }
  }

  public void copyFile(String srcFileName, String destFileName) throws ApplicationException {
    InputStream in = null;
    OutputStream out = null;
    try {
      File srcFile = new File(srcFileName);
      if (! srcFile.exists())
        return; // do nothing
      File destFile = new File(destFileName);
      File destDir = new File(destFile.getParent()); 
      if (! destDir.exists()) {
        destDir.mkdirs();  // create the directory including parent directories which do not exist
      }
      in = new BufferedInputStream(new FileInputStream(srcFile));
      out = new BufferedOutputStream(new FileOutputStream(destFile));
      int bufLen = 20000*1024;
      byte[] buf = new byte[bufLen];
      int len = 0;
      while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
      }
      out.flush();  // buffered content is flushed to file
    } catch (FileNotFoundException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      try { 
        if (in != null) 
          in.close();
        if (out != null)
          out.close();
      } catch (Exception e) {
        // nothing: always close the stream at the end of the method
      }
    }
  }
  
  public void saveUrlToLocalFile(URL srcUrl, String destFileName) throws ApplicationException {
    BufferedInputStream in = null;
    BufferedOutputStream out = null;
    try {
      /* wenn ein Zugriff mit "http:" gemacht wird, wird die XML Deklaration (<?xml version="1.0"?>) nicht ausgelesen 
       * beim Zugriff mit "file;" ist das anders
       * evtl. wieder einbauen, um die Deklaration manuell zu schreiben
      URLConnection urlConn = srcUrl.openConnection();
      String contentTypeStr = urlConn.getContentType();
      String contentEncodingStr = urlConn.getContentEncoding();
      boolean contentTypeXml = false;
      if (contentTypeStr != null) {
        contentTypeStr = contentTypeStr.toLowerCase();
        if (contentTypeStr.indexOf("application/xml") != -1 || contentTypeStr.indexOf("text/xml") != -1)
          contentTypeXml = true;
      }
      */
      InputStream inputStream = srcUrl.openStream();
      in = new BufferedInputStream(inputStream);
      File outputFile = new File(destFileName);
      File outputDir = new File(outputFile.getParent()); 
      if (! outputDir.exists()) {
        outputDir.mkdirs();  // create the directory including parent directories which do not exist
      }
      out = new BufferedOutputStream(new FileOutputStream(outputFile));
      int bufLen = 1000*1024;
      byte[] buf = new byte[bufLen];
      int len = 0;
      /*
      if (contentTypeXml) {
        String xmlDecl = "<?xml version=\"1.0\"?>\n";
        out.write(xmlDecl.getBytes("utf-8"));
      }
      */
      while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
        out.flush();
      }
    } catch (MalformedURLException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      try { 
        if (in != null)
          in.close();
        if (out != null)
          out.close(); 
        } catch (Exception e) { 
          // nothing: always close the stream at the end of the method
        }  
    }
  }
  
  public void saveInputStreamToLocalFile(InputStream srcInputStream, String destFileName) throws ApplicationException {
    BufferedInputStream in = null;
    BufferedOutputStream out = null;
    try {
      in = new BufferedInputStream(srcInputStream);
      File outputFile = new File(destFileName);
      File outputDir = new File(outputFile.getParent()); 
      if (! outputDir.exists()) {
        outputDir.mkdirs();  // create the directory including parent directories which do not exist
      }
      out = new BufferedOutputStream(new FileOutputStream(outputFile));
      int bufLen = 1000*1024;
      byte[] buf = new byte[bufLen];
      int len = 0;
      while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
        out.flush();
      }
    } catch (MalformedURLException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      try { 
        if (in != null)
          in.close(); 
        if (out != null)
          out.close(); 
        } catch (Exception e) { 
          // nothing: always close the stream at the end of the method
        }  
    }
  }
  
  public void deleteLastNBytes(File file, int countBytes) throws ApplicationException {
    try {
      RandomAccessFile raf = new RandomAccessFile(file, "rw");
      long length = raf.length();
      raf.setLength(length - countBytes);
      raf.close();
    } catch (IOException e) {
      throw new ApplicationException(e);
    }
  }
  
  public void testFile(String fileName) throws ApplicationException {
    File file = new File(fileName);
    boolean fileExists = file.exists();
    if (! fileExists) {
      throw new ApplicationException("File: " + fileName + " does not exist");
    }
  }
  
  /**
   *  Reads a chunk of data of an input stream.
   *  Does not close the stream until last bytes are read
   *  @in in the input stream to be read
   *  @chunkSize chunkSize length of the chunk which is read
   *  @return byte[] of bytes read
   */
  public byte[] readBytes(InputStream in, int chunkSize) throws ApplicationException {
    byte[] resultBytes = new byte[chunkSize];
    try {
      int len = in.read(resultBytes, 0, chunkSize);
      if (len == -1) {
        try { in.close(); } catch (Exception e) { }  // close the stream if end of file is reached
        resultBytes = null;
      } else if (len < chunkSize && len != chunkSize) {  // if read chunk is last chunk of the file it delivers this chunk 
        byte[] tmp = new byte[len];
        System.arraycopy(resultBytes, 0, tmp, 0, len);
        resultBytes = tmp;
      }
    } catch (FileNotFoundException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } 
    return resultBytes;  
  }

  /**
   *  Reads a file storing intermediate data into an array.
   *  @file file the file to be read
   *  @return byte[] of file content
   */
  public byte[] readBytes(String fileName) throws ApplicationException {
    InputStream in = null;
    byte[] out = new byte[0]; 
    try {
      in = new BufferedInputStream(new FileInputStream(fileName));
      // the length of a buffer can vary
      int bufLen = 20000*1024;
      byte[] buf = new byte[bufLen];
      byte[] tmp = null;
      int len = 0;
      while((len = in.read(buf, 0, bufLen)) != -1) {
        // extend array
        tmp = new byte[out.length + len];
        System.arraycopy(out, 0, tmp, 0, out.length);
        System.arraycopy(buf, 0, tmp, out.length, len);
        out = tmp;
        tmp = null;            
      }
    } catch (FileNotFoundException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      // always close the stream 
      if (in != null) try { in.close(); } catch (Exception e) { }
    }
    return out;  
  }

  public String getMimeType(String fileName) throws ApplicationException {
    String mimeType = null;
    File file = new File(fileName);
    try {
      URI uri = file.toURI();
      URL url = uri.toURL();
      URLConnection urlConnection = url.openConnection();
      mimeType = urlConnection.getContentType();
    } catch (MalformedURLException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    }
    return mimeType;
  }
  
  /**
   *  Reads a file storing intermediate data into an array.
   *  @file file the file to be read
   *  @return byte array of the file content
   *  TODO test this method if it is really faster
   */
  private byte[] readBytesFast(String file) throws ApplicationException {
    InputStream in = null;
    byte[] buf = null; 
    int bufLen = 20000*1024;
    try {
      in = new BufferedInputStream(new FileInputStream(file));
      buf = new byte[bufLen];
      byte[] tmp = null;
      int len    = 0;
      List data  = new ArrayList(24); // keeps pieces of data
      while((len = in.read(buf, 0, bufLen)) != -1){
        tmp = new byte[len];
        System.arraycopy(buf, 0, tmp, 0, len); // still need to do copy 
        data.add(tmp);
      }
      /* This part os optional. This method could return a List data
         for further processing, etc. */
      len = 0;
      if (data.size() == 1) return (byte[]) data.get(0);
      for (int i=0;i<data.size();i++) len += ((byte[]) data.get(i)).length;
      buf = new byte[len]; // final output buffer 
      len = 0;
      for (int i=0;i<data.size();i++){ // fill with data 
        tmp = (byte[]) data.get(i);
        System.arraycopy(tmp,0,buf,len,tmp.length);
        len += tmp.length;
      } 
    } catch (FileNotFoundException e) {
      throw new ApplicationException(e);
    } catch (IOException e) {
      throw new ApplicationException(e);
    } finally {
      if (in != null) try { in.close(); } catch (Exception e) {}
    }
    return buf;  
  }

  /*
   * 
   Insert a document (today.rss as 20050401) by a URL connection (PUT request):

   URL u = "http://www.cafeaulait.org/today.rss";
   InputStream in = u.openStream();
   URL u = new URL("http://eliza.elharo.com:8080/exist/servlet/db/syndication/20050401");
   HttpURLConnection conn = (HttpURLConnection) u.openConnection();
   conn.setDoOutput(true);
   conn.setRequestMethod("PUT");
   conn.setHeaderField("Content-type", "application/xml");
   OutputStream out = conn.getOutputStream();
   for (int c = in.read(); c != -1; c = in.read()) {
     out.write(c);
   }
   out.flush();
   out.close();
   in.close();
   // read the response...

   Delete a document (20050401) by a URL connection:

   URL u = new URL("http://eliza.elharo.com:8080/exist/servlet/db/syndication/20050401");
   HttpURLConnection conn = (HttpURLConnection) u.openConnection();
   conn.setRequestMethod("DELETE");
   conn.connect();
   // read the response...
   * 
   * 
  */
  
  
}