'encode'에 해당되는 글 1건

  1. 2012.02.06 [JAVA] txt 파일 입출력 관련 팁 - 인코딩(encode) (1)
2012.02.06 02:29
요번에 하는 프로젝트가 안도르이드에서 txt 파일을 가져와서 읽고, 수정한뒤에 저장하는 기능이 있었는데요,

처음엔 엑셀로 구현해놨다가 바껴서 txt 로 읽고 쓰기로 했습니다. 

처음 생각과는 달리 상당히 어려웠습니다. 문제점으로 제일 큰게 인코딩(encode)이었습니다.

안에 있는 데이터엔 한글이 포함되어 있었습니다. 아무런 인코딩 없이 아래와 같이 불러왔을때 한글이 이상한 문자로 깨지는 현상이 생겼습니다. 마름모에 물음표가 들어있는.ㅋㅋ(위키에서 살펴보니, UTF에서 글자를 못찾으면(?) 저 문자로 대체되거나 무시된다고 하는군요)

FileReader fr = new FileReader(src);
BufferedReader br = new BufferedReader(fr);
String line;
data = new ArrayList<String>();
while ((line = br.readLine()) != null) {
	Log.e("Flask_input", line);
	data.add(line);
}
br.close();
fr.close();
문제점을 찾기엔 너무 오래걸렸습니다...ㅠㅠ 먼저 인코딩관련 자료를 찾아보니 자바스크립트에서는 아주쉽게 http디코더였나? 에서 변환해주더군요.

일단 억지로 인코더/디코더 코드를 구해서 적용시켜봤지만, 인터넷 주소에서 쓰이는 %EF%AE%D6 뭐 이런 퍼센트가 들어가있는 문자가 나왔습니다...ㅠㅠ

다시 찾아보니, 이걸다시 변환해줘야;;;;;; 하지만 이게 원천적으로 문제를 해결할 수 없다는것을 깨닫고 다시 구글링을 했습니다.

그래서 구한게 파일을 읽어올때 바이트 코드로 읽는데, 여기에 인코딩해논것으로 읽어오기! 입니다.

File file = new File(src);
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line;
data = new ArrayList<String>();
while ((line = br.readLine()) != null) {
	Log.e("Flask_input", line);
	data.add(line);
}
br.close();
하지만,,,,,가끔 안되는게 있더군요.,.. 그래서 저기 UTF-8 로 되있는것을 EUC-KR로 바꿔보기도 하고 별의별 뻘짓을 해봤지만 아직 해결법은 못찾았습니다. (일단은 저 코드는 동작하는것 같습니다.)

뭐 여기까진 문제가 없었습니다. 그다음 txt에서 한줄을 읽고, 이걸 분해 하려고 substring() 를 사용했습니다.

그런데 이상한 현상이 생깁니다. 바로, subsitrng() 로 얻어온 문자열이 눈으로 볼땐 길이가 7인데, .length()찍어보면 8입니다....엉? 뭐야?

어....음.....머지.......................

하다가, 생각난 charAt()으로 해당 문자열 각각의 문자를 다 찍어보기로 합니다... 찍어보니, 맨 앞 자리가 아무것도 안나옵니다.... 아 뭐야;; 공백 문자인가...해서 int로 캐스팅하고 숫자를 찍어보니 65279 가 나왔습니다....ㅋㅋㅋㅋㅋㅋ아 뭐야.ㅋㅋㅋㅋ 이 숫자는 뭘 의미하는거야.ㅋㅋㅋㅋㅋㅋ

뭐 일단 char는 유니코드를 받으니, 16진수로 변환! 65279 -> 0xFEFF

저 16진수를 찾아보니 텍스트의 파일시작에서 '유니코드' 라고 말해주는 녀석이었습니다.

Big-endian : 0xFEFF
Little-endian : 0xFFFE

이라고 하는데, 자세한건 http://hyyoo.egloos.com/2273029 를 참고....

뭐 어쨋든, 파일의 첫 부분이 저 코드로 시작해서 첫줄의 인덱스가 하나씩 밀려서 글자 하나가 짤리게 되는 현상을 낳았네요....

드디어 문제를 해결하고... 이제 자러갑니다ㅠㅠ

+ 2012-2-7 관련 내용 추가

txt 파일을 출력하면 newLine()이 잘 안될때가 생기네요..

파일에서 맨 앞으로 가라는 CR(Carrge return) 과 다음 줄로 가라는 LF(Line Feed) 를 이용하여 엔터효과를 낼 수 있습니다.

 먼저 여기서 중요한 것이  LF 바로 개행 문자입니다.

아스키코드표에서 보면, 16진수 0x000A  가 개행문자입니다.

여기서 개행문자를 어떻게 주느냐?? 바로 케릭터 타입에담고, 줄 뒤에 붙여서 보내주면 됩니다! 참 쉽죠?

하지만 여기서 문제가 발생합니다. 바로 저 개행문의 유니코드값 '\u000a' 가 케릭터 타입에 안들어갑니다.
(\ 는 역 슬래시 입니다, 넣으려고 하면 오류를 보여줍니다.)

엥? 이게 무슨 소리야? 분명,  char a = '\u005a'  이런건 들어가는데?

찾아보니, 저것이 개행문자로 등록되어 있어서 넣을수(?) 없다느군요? 자세한건 나중에 추가하기로 하고...

그럼 이넘을 어떻게 넣어주느냐?  그냥 16진수 넣듯이 넣어주면 됩니다. 아래처럼 말이죠.
(자바에선  char 은 문자 지만, 숫자 값도 넣을 수 있습니다.)

 char a = 0x000A;

 그러면 정상적으로 들어가고

 String s = "hello world"+a;

 로 해주면 정상적으로 되는것을 확인하실수 있습니다.

자바에서 파일을 쓸때, 아니 윈도우에선 유닉스에서 만든  txt 파일들 가져오면  LF 가 짤려서 나온다고 합니다.
그래서 한줄한줄들이 장인의손길(?)에 의해 한땀한땀 이어진것을 보실수 있게 되는거죠.

의문이  생기는 것이  newLine() 를 해줬음에도 불구하고 개행이 안된다는 점입니다.

자바는 모든 플렛폼에서 구동되도록 설게되엇는뗴 말이죠, 그래서 각  OS 마다 다르게 내부적으로 적용(?)




저작자 표시 비영리 변경 금지
신고
Trackback 0 Comment 1
  1. Favicon of http://heather-hm.tistory.com BlogIcon HeatherHM 2015.02.11 22:59 신고 address edit & del reply

    댓굴 처음달아보네요 ㅋㅋ
    좋은글 감사합니다. 저도 똑같은 문제로 헤메고있었는데 마침 좋운글 잘 보고갑니다 ^^



티스토리 툴바