본문 바로가기

JAVA

[java] file copy or move

[출처] Java File Copy 혹은 Move|작성자 협객

파일 Copy를 java IO에서 해주면 얼마나 좋겠냐 마는.. 그런 API는 없다 -_-;

헌데.. Move는 있다. 오우예!

예를 들어서 아래와 같은 폴더 구조에서 Transfer폴더에 문서들의 키가 있고 성공하면 삭제하고 에러가 나면 Error폴더로 옮겨야 한다고 생각을 해보자.


구현을 하자면 대략 이런 형식이 될 것이다.

private void AfterProcessForError( TDocInfo_KSA docInfo)
{
File fErrorFolder = new File ( ERROR_FOLDER);
if ( fErrorFolder.isDirectory())
{
File fOri = new File ( TRANSFER_FOLDER + File.separator + docInfo.getDocID());

if ( fOri.isDirectory())
{
File fTarget = new File( fErrorFolder.getAbsolutePath() + File.separator + docInfo.getDocID());
try
{
move( fOri, fTarget);
}
catch( IOException e)
{
throw KsaException.makeARCException( e, KsaException.E_LOCAL_FILE_MOVE);
}
}
}
}

move는 renameTo 함수를 이용하면 된다. renameTo는 파일 하나씩도 되고 폴더체 해도 된다.

즉 그래서 위처럼 하면 폴더채 이동이 가능하다.

아래는 move해야할 폴더가 없으면 해당 폴더를 만든후에 move한다.

private void move( File fOri, File fTarget) throws IOException
{
if ( !fTarget.isFile())
{
File fParent = new File ( fTarget.getParent());
if ( !fParent.exists())
{
fParent.mkdir();
}
}

fOri.renameTo( fTarget);
}

그럼.. 만약 카피를 해야한다고 보자. 카피는 어떻게 해야할까?

위의 비즈니스로직상에서 에러가 나면 Transfer폴더는 그대로 두고 문서폴더체Error폴더로 카피를 해야한다고 한다면?

private void AfterProcessForError (TDocInfo_KSA docInfo)
{
File fErrorFolder = new File ( ERROR_FOLDER);
String szOriFolderPath = "";
String szTargetFolderPath = "";

if ( fErrorFolder.isDirectory())
{
File fTargetFolder = new File ( TRANSFER_FOLDER + File.separator + docInfo.getDocID());

if ( fTargetFolder.isDirectory())
{
String[] FileList = fTargetFolder.list();
File fOri = null;
File fTarget = null;

szOriFolderPath = fTargetFolder.getAbsolutePath() + File.separator;
szTargetFolderPath = fErrorFolder.getAbsolutePath() + File.separator + docInfo.getDocID() + File.separator;

for( int i = 0; i < FileList.length; i++)
{
fOri = new File ( szOriFolderPath + FileList[i]);
fTarget = new File ( szTargetFolderPath + FileList[i]);

try
{
copy ( fOri, fTarget);
}
catch( IOException e)
{
throw KsaException.makeARCException( e, KsaException.E_LOCAL_FILE_MOVE);
}
}

}
}
}

카피는 이렇게.

private void copy( File fOrg, File fTarget) throws IOException
{
FileInputStream io = new FileInputStream ( fOrg);

if ( !fTarget.isFile())
{
File fParent = new File ( fTarget.getParent());
if ( !fParent.exists())
{
fParent.mkdir();
}
fTarget.createNewFile();
}


FileOutputStream out = new FileOutputStream ( fTarget);

byte[] bBuffer = new byte[ 1024 * 8];

int nRead;
while ( (nRead = io.read( bBuffer)) != -1)
{
out.write( bBuffer, 0, nRead);
}

io.close();
out.close();
}

이런식으로 간단하게 FileInputStream과 FileOutputStream으로 처리가 가능하다.

카피에서중요한것은 바로 아래부분!

FileOutputStream out = new FileOutputStream ( fTarget);

fTarget은 가야할 목적지의 파일이지 존재하는 파일은 아직 없기 때문에 파일이없다고 오류만 내뱉는다.

그래서 위에서 임시로 파일을 만들어 두어야 한다.

임시로 파일을 만드는 것은 API에서 제공해주는 것이 2가지가 있다.

fTarget.createNewFile();

fTarget.createTempFile( "Temp", ".tmp", new File ( fTarget.getParent()));

해당 파일의 이름대로 만들어주는 createNewFile과 임시파일을 만들어주는 createTempFile이다.

헌데 카피는 파일이름도 맞춰주고 해야 하니.. createTempFile을 쓰는건 비추이다.

끝으로위처럼 스트림으로 짜면 속도가 느리므로 아래처럼 NIO로 짜는게 좋을 듯하다.

private void copy2( File fOrg, File fTarget) throws IOException
{
FileInputStream inputStream = new FileInputStream( fOrg);

if ( !fTarget.isFile())
{
File fParent = new File ( fTarget.getParent());
if ( !fParent.exists())
{
fParent.mkdir();
}
fTarget.createNewFile();
}

FileOutputStream outputStream = new FileOutputStream( fTarget);
FileChannel fcin = inputStream.getChannel();
FileChannel fcout = outputStream.getChannel();

long size = fcin.size();
fcin.transferTo(0, size, fcout);

fcout.close();
fcin.close();
outputStream.close();
inputStream.close();
}

참고로 위의 NIO 방법은 http://www.yunsobi.com/blog/399에서 참조했음을 밝혀둔다.

(좋은 글이므로 모두들 한번씩 보면 좋을듯 하다. ^^)

'JAVA' 카테고리의 다른 글

iBatis 와 spring 연동  (0) 2012.02.17
java framework 링크  (0) 2011.06.30
[java] package 와 import에 대한 설명  (0) 2010.04.23
[JAVA] 자바 코드 튜닝 가이드  (0) 2010.04.12
[JAVA] Vector-&gt;ArrayList, Hashtable -&gt; HashMap  (0) 2010.04.12