Java에서 파일 복사, Object Serialization, byte 배열 문자열 변환은 입출력 코드를 작성할 때 자주 만나는 기본 작업이다. 이 글은 FileInputStream과 FileOutputStream, ObjectOutputStream, ObjectInputStream, EUC-KR 변환, 배열과 List 차이를 함께 모아 둔 예제 메모다.
예제들은 오래된 Android와 Java 코드 흐름을 기준으로 작성되어 있어, 핵심은 스트림을 열고 닫는 순서와 저장할 데이터 형식을 분명히 구분하는 데 있다.
핵심 정리
파일 복사는 입력 스트림에서 byte 버퍼로 읽고 출력 스트림에 쓰는 흐름으로 이해할 수 있다. Object Serialization은 객체를 ObjectOutputStream으로 파일에 저장하고 ObjectInputStream으로 다시 읽어 오는 방식이다. List 같은 객체를 그대로 저장할 수 있어 간단한 캐시에는 편하지만, 클래스 구조가 바뀌거나 호환성을 길게 가져가야 하는 데이터에는 주의가 필요하다. JNI에서 byte 배열을 받아 문자열로 바꿀 때는 원본 인코딩을 정확히 알아야 한다. 원문 예시처럼 EUC-KR이나 MS949 계열 데이터를 다룰 때는 기본 문자셋에 맡기지 말고 명시적으로 인코딩을 지정하는 편이 안전하다. 배열과 List의 차이는 크기 변경 가능 여부로 먼저 구분하면 이해하기 쉽다.
- 파일 복사는 입력 스트림에서 읽고 출력 스트림에 쓰는 흐름으로 구성된다.
- 버퍼를 사용하면 파일을 한 번에 모두 메모리에 올리지 않고 복사할 수 있다.
- 스트림은 작업이 끝난 뒤 반드시 닫아야 한다.
- ObjectOutputStream은 객체를 파일로 저장할 때 사용할 수 있다.
- ObjectInputStream은 저장된 객체를 다시 읽어 올 때 사용한다.
- 직렬화 파일은 클래스 변경과 호환성 문제를 고려해야 한다.
- byte 배열을 문자열로 바꿀 때는 EUC-KR 같은 원본 인코딩을 명시한다.
- 배열은 크기가 고정되고 List는 동적으로 크기를 바꿀 수 있다.
원문은 Java와 Android 작업 중 필요했던 짧은 코드 조각을 한곳에 모은 메모입니다. 보강문에서는 파일 복사, 객체 직렬화, 문자 인코딩, 배열과 List를 각각 어떤 상황에서 보는지 분리했습니다. 최신 코드에서는 더 간결한 API를 선택할 수도 있지만, 스트림과 직렬화의 기본 동작을 이해하는 데는 원문의 예제가 여전히 유용합니다.
자바랑 안드로이드랑 내용이 많아서 분리함 :)
file
파일복사하기
의외로 간단하지 않더라?
protected void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
copy(new File("src.xml"), new File("tar.xml"));
object serialization
List<String> 파일로 저장하고 빼기
저장하기
try{
String cur_path = _activity.getFilesDir().getAbsolutePath();
FileOutputStream fileOut = new FileOutputStream(cur_path + "/list_cache.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(_strListAll);
out.close();
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
로딩하기
try {
String cur_path = _activity.getFilesDir().getAbsolutePath();
FileInputStream fileIn = new FileInputStream(cur_path + "/list_cache.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
_strListAll = (List<String>)in.readObject();
in.close();;
fileIn.close();
} catch (FileNotFoundException ee) {
e.printStackTrace();
} catch (IOException ee) {
e.printStackTrace();
} catch (ClassNotFoundException ee) {
e.printStackTrace();
}
String
byte array
* euc-kr buffer를 jni를 통해서 가져온다음에 String으로 변환하는 작업을 하였다.
* 아래 코드 참조하자
//java side
public native byte[] SvBadukDBClientGetTitle();
byte[] btitle = SvBadukDBClientGetTitle();
String title;
try {
title = new String(btitle, "EUC-KR");
}
catch (UnsupportedEncodingException e){}
//c side
jbyteArray as_byte_array(JNIEnv* env, char* buf, int len) {
jbyteArray array = env->NewByteArray (len);
env->SetByteArrayRegion (array, 0, len, reinterpret_cast<jbyte*>(buf));
return array;
}
//TODO: check jbytearray possible memory-leak issue
jbyteArray Java_com_sevity_jungsuk_BadukPanView_SvBadukDBClientGetTitle
(JNIEnv* env, jobject thiz)
{
g_env = env;
g_thiz = thiz;
char msg[4096] = {};
SvBadukDBClient_GetTitle((char*)msg);
//jbyteArray result = as_byte_array(env, msg, strlen(msg));
//return result;
jbyteArray result = as_byte_array(env, msg, strlen(msg));
return result;
}
인코딩
* MS949관련 여기서 확인
* 파일 인코딩 변환 코드 여기서 확인
배열
* 미리 개수를 알 때는 String[] strArr = {"맹구", "땡칠이"} 이렇게 하면되는데..
* 또는 String[] strArr = new String[10]; 이렇게 하면 되는데.. 배열은 크기가 정해져 있다.
* 자세한건 여기 참조..
* 동적으로 개수를 조정하는건 위의 방식으로 안되는듯 하다.
리스트
* 동적으로 개수를 조정하려면 리스트를 써야 한다.
* 여기를 참조하자.
* ArrayList<String> pitches = new ArrayList<String>(); 이런식으로 하거나
* List<String> pitches = new ArrayList<String>(); 이런식으로 하면된다.
* 위 둘 중에 아래가 좀 더 바람직(?) 한 것 같고 이유는 여기를 참조하자.
assert
* 어이없게도 android studio에서 assert가 잘 안먹는다.
* 일단 커서 갖다대로 변환하면 자동으로 if..throw 문으로 번역해주긴 하는데..
* 아무래도 java용 라이브러리 하나 구축해야겠다; SVASSERT 먹도록 해야할 것 같다.
'Programming' 카테고리의 다른 글
| OCX 로딩 오류와 Windows 개발 이슈 정리 (0) | 2026.05.16 |
|---|---|
| 회귀 뜻과 회귀분석, 선형회귀, 로지스틱 회귀 정리 (0) | 2026.05.16 |
| YAML 설정 오류 방지: 허용되지 않은 key 검증 (0) | 2026.05.15 |
| Linux 명령어 메모: 네트워크 트래픽, 압축, tar 사용법 (0) | 2026.05.11 |
| Go 언어 특징: goroutine, error 처리, 웹 서버 (0) | 2025.05.25 |
