All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nablarch.core.util.FileUtil Maven / Gradle / Ivy

The newest version!
package nablarch.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

import nablarch.core.util.annotation.Published;


/**
 * ファイルの取り扱いに関するユーティリティクラス。
 *
 * @author Koichi Asano
 * @author Masato Inoue
 */
@Published(tag = "architect")
public final class FileUtil {

    /** 隠蔽コンストラクタ。 */
    private FileUtil() {
    }

    /**
     * リソースを解放する。
     * 

* 例外が発生した場合は何もせず、次のリソース解放を行う。 * * @param closeables リソース解放を行うクラス */ public static void closeQuietly(Closeable... closeables) { if (closeables == null) { return; } for (Closeable closeable : closeables) { try { if (closeable != null) { closeable.close(); } } catch (IOException e) { // SUPPRESS CHECKSTYLE 例外を抑止するため } catch (RuntimeException e) { // SUPPRESS CHECKSTYLE 例外を抑止するため // closable.close() で実行時例外が発生した場合に、呼び出し元の finally 句でエラーが発生してしまうことを考慮してもみ消す。 } } } /** * リソースを取得する。 *

* ファイルパスまたはクラスパス上のリソースを取得する。
* 引数に指定するURLのフォーマットは下記の通り。 *

     *     <スキーム名>:<リソースのパス>
     * 
* URLの指定例を下記に示す。 *
     * //ファイルパスの場合
     * FileUtil.getResource("file:/var/log/log.properties");
     *
     * //クラスパスの場合
     * FileUtil.getResource("classpath:nablarch/core/log/log.properties");
     * 
* * @param url URL * @return リソースのストリーム * @throws IllegalArgumentException リソースを取得できなかった場合 * @throws java.io.FileNotFoundException リソースファイルが見つからなかった場合 */ public static InputStream getResource(String url) throws IllegalArgumentException { URL resourceURL = getResourceURL(url); try { return resourceURL.openStream(); } catch (Throwable e) { throw new IllegalArgumentException("resource open failed. url = [" + url + "].", e); } } /** * URLを取得する。 *

* ファイルパスまたはクラスパス上のURLを取得する。
* 引数に指定するURLのフォーマットは下記の通り。 *

     *     {@literal <スキーム名>:<リソースのパス>}
     * 
* URLの指定例を下記に示す。 *
     * //ファイルパスの場合
     * FileUtil.getResourceURL("file:/var/log/log.properties");
     *
     * //クラスパスの場合
     * FileUtil.getResourceURL("classpath:nablarch/core/log/log.properties");
     * 
* * @param url URL文字列 * @return リソースのURL * @throws IllegalArgumentException URLが{@code null}または不正だった場合 */ public static URL getResourceURL(String url) { if (url == null) { throw new IllegalArgumentException( "the parameter 'url' is required."); } if (url.startsWith("classpath:")) { return getClasspathResourceURL(url.substring("classpath:".length())); } try { return new URL(url); } catch (MalformedURLException e) { throw new IllegalArgumentException(String.format("illegal url was specified. path=[%s]", url), e); } } /** * クラスパス上のリソースを取得する。 *

* 以下に例を示す。 *

     * FileUtil.getClasspathResource("nablarch/core/log/log.properties");
     * 
* * @param path クラスパス * @return リソースのストリーム * @throws IllegalArgumentException クラスパス及びクラスパスから取得するURLが{@code null}または、リソースが見つからない場合 */ public static InputStream getClasspathResource(String path) throws IllegalArgumentException { if (path == null) { throw new IllegalArgumentException( "the parameter 'path' is required."); } URL url = getClasspathResourceURL(path); if (url == null) { throw new IllegalArgumentException( "the resource path[" + path + "] could not be found."); } InputStream inStream; try { inStream = url.openStream(); } catch (Throwable e) { throw new IllegalArgumentException("It failed to get the resource[" + url + "].", e); } return inStream; } /** * クラスパス上のURLを取得する。 *

* 以下に例を示す。 *

     * FileUtil.getClasspathResource("nablarch/core/log/log.properties");
     * 
* * @param path リソースのパス * @return リソースのURL * @throws IllegalArgumentException クラスパスが{@code null}だった場合 */ public static URL getClasspathResourceURL(String path) { if (path == null) { throw new IllegalArgumentException( "the parameter 'path' is required."); } ClassLoader loader = Thread.currentThread().getContextClassLoader(); return loader.getResource(path); } /** * ディレクトリ配下のファイルおよびディレクトリを検索し、名前で昇順ソートした結果の配列を返す。 *

* ファイル名にはワイルドカード("*")を指定できる。
* ディレクトリは、絶対パスまたは相対パスで指定する。
* ディレクトリが{@code null}だった場合、引数のファイル名を元に構築したFileオブジェクトを持つ要素が1つの配列が返される。
* * @param dir ディレクトリ(null指定の場合、指定なし) * @param name ファイル名 * @return 検索結果の配列 * @throws NullPointerException ファイル名が{@code null}だった場合 */ public static File[] listFiles(String dir, final String name) { if (dir == null) { return new File[]{ new File(name)}; } File dirFile = new File(dir); FilenameFilter filter; filter = new FilenameFilter() { private Pattern pattern = Pattern.compile(name.replace( "\\", "\\\\").replace("*", ".*").replace("/", "\\/")); public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }; File[] unsortedFiles = dirFile.listFiles(filter); if (unsortedFiles == null) { return null; } List files = Arrays.asList(unsortedFiles); // File#listFiles() は "There is no guarantee that the name strings in the resulting array will appear in any // specific order" // であるため、念のために自前でソートを行う。 Comparator comparator = new Comparator() { public int compare(File f1, File f2) { return f1.getName().compareTo(f2.getName()); } }; Collections.sort(files, comparator); return files.toArray(new File[files.size()]); } /** * ファイルを削除する。 * * @param file 削除するファイル * @return ファイルが削除に成功した場合は{@code true}、失敗した場合は{@code false}を返却する。ファイルが存在しない場合は{@code true}を返却する。 * @throws IllegalArgumentException 削除するファイルが{@code null}だった場合 */ public static boolean deleteFile(File file) { if (file == null) { throw new IllegalArgumentException("file is null."); } if (!file.exists()) { return true; } if (!file.delete()) { return false; } return true; } /** * ファイル名から拡張子を抽出する。 *

* 以下の仕様に当てはまる場合は、空文字列を返す。 *

    *
  1. ファイル名の先頭がドット
  2. *
  3. ファイル名の末尾がドット
  4. *
  5. 拡張子にドットがない
  6. *
  7. 拡張子が英数字以外
  8. *
* * @param fileName ファイル名 * @return 拡張子 * @throws IllegalArgumentException ファイル名が{@code null}だった場合 */ public static String extractSuffix(String fileName) { if (fileName == null) { throw new IllegalArgumentException("argument must not be null."); } int start = fileName.lastIndexOf("."); if (start == -1) { // ドットが無い return ""; } if (start == 0) { // ファイル名先頭がドット return ""; } // 拡張子 String ext = fileName.substring(start); if (ext.length() == 1) { // ファイル名末尾がドット return ""; } // ドットを省いた拡張子部分 String extWithOutDot = ext.substring(1); // 非ASCII文字の場合、拡張子とはみなさない。 if (!ALNUM_CHAR_PATTERN.matcher(extWithOutDot).matches()) { return ""; } return ext; } // CHANGE validationへの依存を切るため、自前で英数字判定する。 private static Pattern ALNUM_CHAR_PATTERN = Pattern.compile("[0-9a-zA-Z]*"); /** * ファイルを移動する。 *

* 移動先に同名のファイルが存在していた場合、上書きする。 * * @param src 移動元ファイル * @param dest 移動先ファイル * @throws IllegalArgumentException 移動元ファイルまたは移動先ファイルが{@code null}の場合 * @throws RuntimeException コピー元のファイルが削除できなかった場合 */ public static void move(File src, File dest) { if (src == null) { throw new IllegalArgumentException("src must not be null."); } if (dest == null) { throw new IllegalArgumentException("dest must not be null."); } if (src.renameTo(dest)) { return; } // コピー後、オリジナルを削除 copy(src, dest); if (!deleteFile(src)) { throw new RuntimeException( "Failed to delete original file " + "[" + src.getAbsolutePath() + "]" + ", after copying to [" + dest.getAbsolutePath() + "]"); } } /** * ファイルをコピーする。 *

* コピー先に同名のファイルが存在していた場合、上書きする。 * * @param src コピー元ファイル * @param dest コピー先ファイル * @throws IllegalArgumentException コピー元ファイルまたはコピー先ファイルが{@code null}の場合 * @throws RuntimeException コピーに失敗した場合 */ public static void copy(File src, File dest) { if (src == null) { throw new IllegalArgumentException("src must not be null."); } if (dest == null) { throw new IllegalArgumentException("dest must not be null."); } InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(src)); out = new BufferedOutputStream(new FileOutputStream(dest)); copy(in, out); } catch (IOException e) { throw new RuntimeException( "Failed to copy file." + " src=[" + src.getAbsolutePath() + "]" + " to=[" + dest.getAbsolutePath() + "]", e); } finally { closeQuietly(in, out); } } /** * ストリームのコピーを行う。 * * @param src コピー元入力ストリーム * @param dest コピー先出力ストリーム * @throws IOException 入出力例外 */ private static void copy(InputStream src, OutputStream dest) throws IOException { int b; while ((b = src.read()) != -1) { dest.write(b); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy