본문 바로가기

언어/Java

FileCopy 예제

oop> java -cp bin FileCopy

복사할 원본파일명을 입력하세요 : D:\a.txt

붙여넣기할 파일명을 입력하세요: D:\acopy.txt

<<byte단위로 읽고 쓰기>>

원본파일이 없는 경우 "복사할 원본파일이 없습니다" 메세지 출력된다

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class FileCopy {
	public static void main(String[] args) {
		Scanner sc =new Scanner(System.in);
		System.out.print("원본파일명:");
		String originFileName = sc.nextLine();
		System.out.print("복제본파일명:");
		String copyFileName = sc.nextLine();	
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			fis = new FileInputStream(originFileName);
		} catch (FileNotFoundException e) {
			System.out.println("원본파일이 없습니다");
//			e.printStackTrace();
			return;
		}
			
		try {
			fos = new FileOutputStream(copyFileName);
		} catch (FileNotFoundException e) {	
        //E드라이브 없는데 E드라이브에 만들라하면 이러한 exception
			e.printStackTrace();
			return;
		}
		
		/*
		int readValue;	
		try {
			while((readValue = fis.read()) != -1) {	
            // 끝을 만나면 -1을 반환한다. 마우스 올리면 설명
				fos.write(readValue);
			}
		} catch (IOException e) {
			e.printStackTrace();
		*/
		
		int readCnt; // 읽어온 바이트수
		byte[] bArr= new byte[1024];	
		try {
			while((readCnt = fis.read(bArr)) != -1) {
//				fos.write(bArr); // 이거는 틀림. 
//다시 돌릴때마다 읽어온 바이트수마다 써야해서
				fos.write(bArr, 0, readCnt);	
                // 배열의 0번 인덱스부터, 1kb씩 읽어서 1kb씩 쓰기
			}
		} catch (IOException e) {
			e.printStackTrace();
				
				
		} finally {
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

결과
마이너스1 반환되는 이유
offset

※  Java의 파일 출력 스트림에서 사용되는 메서드로, 지정된 바이트 배열의 특정 위치에서부터 지정된 길이만큼 바이트를 파일로 출력하는 역할을 합니다. 이때 "offset"은 시작 위치를 나타냅니다.

b: 출력할 바이트 배열
off: 시작 위치 (offset), 바이트 배열에서 어디서부터 데이터를 읽을지를 나타냅니다.
len: 출력할 바이트 수

이 메서드를 호출하면, 지정된 바이트 배열(b)에서 off 위치부터 시작하여 len만큼의 바이트를 파일 출력 스트림에 쓰게 됩니다. 즉, 바이트 배열 내에서 off부터 off + len - 1 위치까지의 바이트 데이터가 파일로 출력됩니다.

byte[] data = {65, 66, 67, 68, 69}; // ASCII values for A, B, C, D, E
fos.write(data, 1, 3);

위 코드는 data 배열의 1번째 위치에서 시작하여 3개의 바이트를 파일 출력 스트림에 쓰게 됩니다. 따라서 파일에는 'B', 'C', 'D' 바이트가 순서대로 저장될 것입니다.

 

※ 파일 복사 예제 2

파일 복사의 원리는 FileInputStream에서 읽은 바이트를 바로 FileOutputStream으로 출력하는 것.

임의의 JPEG 그림 파일을 하나 준비해 파일 이름을 test.jpg로 변경한 다음 C:/Temp 폴더에 저장한다.

package ch18.sec03.exam03;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class CopyExample {
	public static void main(String[] args) throws Exception {
		String originalFileName = "C:/Temp/test.jpg";
		String targetFileName = "C:/Temp/test2.jpg";
		
        // 입출력 스트림 생성
		InputStream is = new FileInputStream(originalFileName);
		OutputStream os = new FileOutputStream(targetFileName);
		
        // 읽은 바이트를 저장할 배열 생성
		byte[] data = new byte[1024];
		while(true) {
			int num = is.read(data); // 최대 1024바이트를 읽고 배열에 저장, 읽은 바이트는 리턴
			if(num == -1) break; // 파일을 다 읽으면  while문 종료
			os.write(data, 0, num); // 읽은 바이트 수만큼 출력
		}
			
		os.flush(); // 내부 버퍼 잔류 바이트를 출력하고 버퍼를 비움
		os.close();
		is.close();
		
		System.out.println("복사가 잘 되었습니다.");
	}
}

Java 9부터 좀 더 편리하게 입력 스트림에서 출력 스트림으로 바이트를 복사하는 transferTo() 메소드가
InputStream에 추가되었다. 위 코드에서 아래 라인은 다음과 같이 한줄로 대체가 가능하다.

// 16~21 라인
byte[] data = new byte[1024];
while(true) {
int num = is.read(data);
if(num == -1) break;
os.write(data, 0, num);
}

// 대체
is.transferTo(os);

'언어 > Java' 카테고리의 다른 글

필터스트림, 객체직렬화  (0) 2023.08.09
메타클래스, File 정보 가져오기  (0) 2023.08.09
입출력 스트림 예시  (0) 2023.08.09
프린트 스트림, System.in 예시  (0) 2023.08.09
입출력 스트림(Stream)  (0) 2023.08.09