/* * Copyright 2008-2009 MOPAS(Ministry of Public Administration and Security). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package egovframework.rte.fdl.filehandling; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; import egovframework.rte.fdl.logging.util.EgovResourceReleaser; import egovframework.rte.fdl.string.EgovStringUtil; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.vfs2.FileContent; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemManager; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.Selectors; import org.apache.commons.vfs2.VFS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 파일 서비스을 제공하는 유틸 클래스. * * <p><b>NOTE:</b> 파일 서비스를 제공하기 위해 구현한 클래스이다.</p> * * @author 실행환경 개발팀 윤성종 * @since 2009.06.01 * @version 1.0 * @see <pre> * == 개정이력(Modification Information) == * * 수정일 수정자 수정내용 * ------- -------- --------------------------- * 2009.06.01 윤성종 최초 생성 * 2014.05.14 이기하 vfs -> vfs2로 패키지 변경 * * </pre> */ public class EgovFileUtil { /** * 에러나 이벤트와 관련된 각종 메시지를 로깅하기 위한 Log 오브젝트. */ private static final Logger LOGGER = LoggerFactory.getLogger(EgovFileUtil.class); private static final int BUFFER_SIZE = 1024; private static FileObject basefile; private static FileSystemManager manager; static { try { manager = VFS.getManager(); basefile = manager.resolveFile(System.getProperty("user.dir")); LOGGER.debug("basefile : {}", basefile); } catch (FileSystemException e) { LOGGER.error("EgovFileUtil : {}", e.getMessage()); } } /** * 지정한 위치의 파일 및 디렉토리를 삭제한다. * * @param cmd <code>String</code> * @return 결과 값 * @throws FileSystemException */ public static int rm(final String cmd) throws FileSystemException { int result = -1; try { final FileObject file = manager.resolveFile(basefile, cmd); result = file.delete(Selectors.SELECT_SELF_AND_CHILDREN); LOGGER.debug("result is {}", result); } catch (FileSystemException e) { LOGGER.error(e.toString()); throw new FileSystemException(e); } return result; } /** * 지정한 위치의 파일을 대상 위치로 복사한다. * * @param source <code>String</code> * @param target <code>String</code> * @throws Exception */ public static void cp(String source, String target) throws Exception { try { final FileObject src = manager.resolveFile(basefile, source); FileObject dest = manager.resolveFile(basefile, target); if (dest.exists() && dest.getType() == FileType.FOLDER) { dest = dest.resolveFile(src.getName().getBaseName()); } dest.copyFrom(src, Selectors.SELECT_ALL); } catch (FileSystemException fse) { LOGGER.error(fse.toString()); throw new FileSystemException(fse); } } /** * 지정한 위치의 파일을 대상 위치로 이동한다. * * @param source <code>String</code> * @param target <code>String</code> * @throws Exception */ public static void mv(String source, String target) throws Exception { try { final FileObject src = manager.resolveFile(basefile, source); FileObject dest = manager.resolveFile(basefile, target); if (dest.exists() && dest.getType() == FileType.FOLDER) { dest = dest.resolveFile(src.getName().getBaseName()); } src.moveTo(dest); } catch (FileSystemException fse) { LOGGER.error(fse.toString()); throw new FileSystemException(fse); } } /** * 현재 작업위치를 리턴한다. * * @return 현재 위치 */ public static FileName pwd() { return basefile.getName(); } /** * 파일의 일시를 현재 일시로 변경한다. * * @param filepath <code>String</code> * @return * @throws Exception */ public static long touch(final String filepath) throws Exception { long currentTime = 0; final FileObject file = manager.resolveFile(basefile, filepath); if (!file.exists()) { file.createFile(); } currentTime = System.currentTimeMillis(); file.getContent().setLastModifiedTime(currentTime); return currentTime; } /** * 현재 작업공간의 위치를 지정한 위치로 이동한다. * * @param changDirectory <code>String</code> * @throws Exception */ public static void cd(final String changDirectory) throws Exception { final String path; if (!EgovStringUtil.isNull(changDirectory)) { path = changDirectory; } else { path = System.getProperty("user.home"); } // Locate and validate the folder FileObject tmp = manager.resolveFile(basefile, path); if (tmp.exists()) { basefile = tmp; } else { LOGGER.info("Folder does not exist: {}", tmp.getName()); } LOGGER.info("Current folder is {}", basefile.getName()); } /** * 지정한 위치의 파일목록을 조회한다. * * @param cmd <code>String[]</code> * @return 조회된 파일 목록 * @throws FileSystemException */ public List<?> ls(final String[] cmd) throws FileSystemException { List<Object> list = new ArrayList<Object>(); int pos = 1; final boolean recursive; if (cmd.length > pos && cmd[pos].equals("-R")) { recursive = true; pos++; } else { recursive = false; } final FileObject file; if (cmd.length > pos) { file = manager.resolveFile(basefile, cmd[pos]); } else { file = basefile; } if (file.getType() == FileType.FOLDER) { // List the contents LOGGER.info("Contents of {}", file.getName()); LOGGER.info("info: {}", listChildren(file, recursive, "")); // list.add(file.getName()); } else { // Stat the file LOGGER.info("info: {}", file.getName()); final FileContent content = file.getContent(); LOGGER.info("Size: {}bytes.", content.getSize()); final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); final String lastMod = dateFormat.format(new Date(content.getLastModifiedTime())); LOGGER.info("Last modified: {}", lastMod); } return list; } /** * 지정한 위치의 하위 디렉토리 목록을 가져온다. * * @param dir <code>FileObject</code> * @param recursive <code>boolean</code> * @param prefix <code>String</code> * @return 디렉토리 목록 * @throws FileSystemException */ private StringBuffer listChildren(final FileObject dir, final boolean recursive, final String prefix) throws FileSystemException { StringBuffer line = new StringBuffer(); final FileObject[] children = dir.getChildren(); for (int i = 0; i < children.length; i++) { final FileObject child = children[i]; // LOGGER.info(prefix + child.getName().getBaseName()); line.append(prefix).append(child.getName().getBaseName()); if (child.getType() == FileType.FOLDER) { // LOGGER.info("/"); line.append("/"); if (recursive) { line.append(listChildren(child, recursive, prefix + " ")); } } else { line.append(""); } } return line; } /** * 파일을 읽는다. * * @param file <code>File</code> * @return 결과 값 * @throws IOException */ public static String readFile(File file) throws IOException { BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); return readFileContent(in); } /** * String 형으로 파일의 내용을 읽는다. * * @param the file input stream <code>InputStrea</code> * @return 파일 내용 * @throws IOException */ public static String readFileContent(InputStream in) throws IOException { StringBuffer buf = new StringBuffer(); for (int i = in.read(); i != -1; i = in.read()) { buf.append((char) i); } return buf.toString(); } /** * String 영으로 파일의 내용을 읽는다. * * @param file <code>File</code> * @param encoding <code>String</code> * @return 파일 내용 * @throws IOException */ public static String readFile(File file, String encoding) throws IOException { StringBuffer sb = new StringBuffer(); List<String> lines = FileUtils.readLines(file, encoding); for (Iterator<String> it = lines.iterator();;) { sb.append(it.next()); if (it.hasNext()) { sb.append(""); } else { break; } } return sb.toString(); } /** * 텍스트 내용을 파일로 쓴다. * * @param file <code>File</code> * @param text <code>String</code> */ public static void writeFile(File file, String text) { FileWriter writer = null; try { writer = new FileWriter(file); writer.write(text); } catch (Exception e) { LOGGER.error("Error creating File: {} : {}", file.getName(), e); return; } finally { EgovResourceReleaser.close(writer); } } /** * 텍스트 내용을 파일로 쓴다. * * @param fileName <code>String</code> * @param text <code>String</code> */ public static void writeFile(String fileName, String text) { writeFile(new File(fileName), text); } public static void writeFile(String fileName, String data, String encoding) throws IOException { FileUtils.writeStringToFile(new File(fileName), data, encoding); } /** * byte형으로 파일의 내용을 읽어온다. * * @param file <code>FileObject</code> * @return 파일 내용 * @throws IOException */ public static byte[] getContent(final FileObject file) throws IOException { final FileContent content = file.getContent(); final int size = (int) content.getSize(); final byte[] buf = new byte[size]; final InputStream in = content.getInputStream(); try { int read = 0; for (int pos = 0; pos < size && read >= 0; pos += read) { read = in.read(buf, pos, size - pos); } } finally { EgovResourceReleaser.close(in); } return buf; } /** * 내용을 파일에 OutputStream 으로 저장한다. * * @param file * @param outstr * @throws IOException */ public static void writeContent(final FileObject file, final OutputStream outstr) throws IOException { final InputStream instr = file.getContent().getInputStream(); try { final byte[] buffer = new byte[BUFFER_SIZE]; while (true) { final int nread = instr.read(buffer); if (nread < 0) { break; } outstr.write(buffer, 0, nread); } } finally { EgovResourceReleaser.close(instr); } } // Create the output stream via getContent(), to pick up the validation it does /** * 파일 객체를 대상 파일객체로 복사한다. * * @param srcFile <code>FileObject</code> * @param destFile <code>FileObject</code> * @throws IOException */ public static void copyContent(final FileObject srcFile, final FileObject destFile) throws IOException { final OutputStream outstr = destFile.getContent().getOutputStream(); try { writeContent(srcFile, outstr); } finally { EgovResourceReleaser.close(outstr); } } /** * 파일의 확장자를 가져온다. * * @param filename <code>String</code> * @return 파일확장자 */ public static String getFileExtension(String filename) { return FilenameUtils.getExtension(filename); } /** * 파일의 존재여부를 확인한다. * * @param filename <code>String</code> * @return 존재여부 */ public static boolean isExistsFile(String filename) { File file = new File(filename); return file.exists(); } /** * 디렉토리명을 제외한 파일명을 가져온다. * * @param filename <code>String</code> * @return */ public static String stripFilename(String filename) { return FilenameUtils.getBaseName(filename); } /** * 저정한 파일을 삭제한다. * * @param file <code>File</code> * @throws IOException */ public static void delete(File file) throws IOException { if (file.isDirectory()) { // it's a folder, list children first File[] children = file.listFiles(); for (int i = 0; i < children.length; i++) { delete(children[i]); } } if (!file.delete()) { throw new IOException("Unable to delete " + file.getPath()); } } /** * 텍스트 파일을 읽어온다. * * @param fileName <code>String</code> * @param newline <code>boolean</code> * @return 파일 내용 * @throws FileNotFoundException * @throws IOException */ public static StringBuffer readTextFile(String fileName, boolean newline) throws FileNotFoundException, IOException { File file = new File(fileName); if (!file.exists()) { throw new FileNotFoundException(); } StringBuffer buf = new StringBuffer(); BufferedReader in = null; try { in = new BufferedReader(new FileReader(file)); String str; while ((str = in.readLine()) != null) { buf.append(str); if (newline) { buf.append(System.getProperty("line.separator")); } } } finally { EgovResourceReleaser.close(in); } return buf; } /** * 특정위치의 파일 객체를 가져온다. * * @param filepath <code>String</code> * @return 파일 객체 * @throws Exception */ public static FileObject getFileObject(final String filepath) throws Exception { FileSystemManager mgr = VFS.getManager(); return mgr.resolveFile(mgr.resolveFile(System.getProperty("user.dir")), filepath); } /** * 특정 패턴이 존재하는 파일을 검색한다. * * @param search <code>Object[]</code> * @param pattern <code>String</code> * @return 파일 목록 * @throws Exception */ public static List<String> grep(final Object[] search, final String pattern) throws Exception { Pattern searchPattern = Pattern.compile(pattern); String[] strings = searchPattern.split(search.toString()); List<String> list = new ArrayList<String>(); for (int i = 0; i < strings.length; i++) { list.add(strings[i]); } return list; } /** * 특정 패턴이 존재하는 파일을 검색한다. * * @param file <code>File</code> * @param pattern <code>String</code> * @return 파일 목록 * @throws Exception */ public static List<String> grep(final File file, final String pattern) throws Exception { Pattern searchPattern = Pattern.compile(pattern); List<String> lists = FileUtils.readLines(file); Object[] search = lists.toArray(); String[] strings = searchPattern.split(search.toString()); List<String> list = new ArrayList<String>(); for (int i = 0; i < strings.length; i++) { list.add(strings[i]); } return list; } /** * 시스템 임시 디렉토리를 얻어온다. * * @return * @throws IOException */ public static String getTmpDirectory() throws IOException { File baseDir = new File(System.getProperty("java.io.tmpdir")); return baseDir.getCanonicalPath(); } }