[ java ] in KIDS 글 쓴 이(By): guest (guest) 날 짜 (Date): 1997년12월29일(월) 18시00분11초 ROK 제 목(Title): Re: [질문] servlet에서 string ... 파일 중간에서 뒤의 내용들을 뒤로 밀어내고 새로운 내용을 추가하는 방법이라면 당연히 삽입할 부분부터 새로 써주는 수 밖에 없다는 것은 아시리라 생각합니다. 다음은 news:han.comp.lang.java에서 퍼온 글입니다. ------------------------------------------------------------------ Sun, 21 Dec 1997 23:14:59 han.comp.lang.java Thread 813 of 843 Lines 83 Re: 자바에서 파일내용을 수정할 수 있는 RespNo 1 of 1 dynaxis@ivory.kaist.ac.kr Kim Do-Hyung at PL lab., CSD, KAIST 성 시 완 <s_orion1@hanbat.chungnam.ac.kr> wrote: : [생략] : 그런데 저는 이 파일의 내용을 계속 : 해서 수정해서 업데이트 해주어야 하는데, 파일 내용에 덧붙이는 것이 아니고 : 파일의 내용중 일부를 수정하여 다시 이 파일에 기록해야 되는데, 방법이 쉽지 : 않습니다. java.sun.com에 가서 api를 참조하여 가능한 메소드를 찾아 보았는데, : 파일에 문자열을 기록하는 메소드가 있었습니다. 저는 파일 내용중에 일부 : 문자열을 새로운 문자열로 바꿀 필요가 있어서 다음과 같은 메소드를 썼습니다. : PrintWriter out : = new PrintWriter(new BufferedWriter(new FileWriter("test.txt"))); : out.write("갱신할 문자열"); : out.close(); : 그런데 이 메소드를 수행한후 test.txt라는 파일을 열어보면 "갱신할 : 문자열"만 있고 나머지 내용은 온데 간데 없습니다. FileWriter의 경우 file의 끝에 append하거나 파일 전체를 잘라내버리거나 두가지중 한가지만 가능합니다. 내부적으로 FileOutputStream를 사용하므로 FileOutputStream의 한계를 그대로 가지고 있다고 볼 수 있습니다. : 이 문제 해결을 위해 조언을 좀 부탁드립니다. 문제 설명이 미흡해 : 죄송합니다. 요지는 파일에서 일부 내용을 덧 붙이는 것이 아니고 수정할 수 : 있는 방법에 대하여 알고 싶습니다. 바쁘실 텐데 자꾸 괴롭혀 죄송합니다. : 아울러 좋은 성탄들 맞으시고, 다가오는 새해에 축복을 기원합니다. : 안녕히... 첫째, 파일의 일부를 수정하는 경우는 RandomAccessFile 클래스를 사용하도록 되어 있습니다. 문제는 이 클래스의 메쏘드들중에서 유니코드에서 KSC5601로의 변환을 해 주는 메쏘드가 없다는 점입니다. 즉, 자바가 실행되는 플랫폼의 문자코드로 변환하는 기능을 가진 것이 없습니다. JDK 1.1에서 코드변환을 지원하는 것은 오로지 OutputStreamWriter와 InputStreamReader뿐입니다. 따라서, 파일자체가 KSC5601의 한글코드를 가질 필요가 없다면 RandomAccessFile을 사용하여 문자열을 UTF나 유니코드로 저장할 것을 권해 드립니다. 둘째, 잘 쓰지 않는 방법이지만, FileDescriptor를 이용해서 쓰고 읽을 위치만 RandomAccessFile의 seek() 메쏘드로 지정을 해 주고, 실제 입출력은 FileReader와 FileWriter로 해주는 것입니다. 다음의 예제를 보시죠. import java.io.*; class FDTest { public static void main(String[] argv) throws IOException { RandomAccessFile file = new RandomAccessFile("test.txt", "rw"); FileWriter fw = new FileWriter(file.getFD()); // seek는 RandomAccessFile에, write는 FileWriter로... file.seek(10); fw.write("바꾸자"); // close를 하는 순서가 중요합니다. fw.close(); file.close(); } } 간단히 짠 예제이니 핵심만 파악하시기 바랍니다. ^^; test.txt를 시험중 --000000-- 시험중 정도로 해 주시고, 위 프로그램을 실행해 보십시오. 000000 부분이 "바꾸자"로 바뀝니다. FileDescriptor가 실제 파일을 읽고 쓰는 현재 상태를 나타내는 객체이므로 같은 FileDescriptor를 공유한 RandomAccessFile과 FileWriter가 서로 영향을 받는 것이지요. 아마도 이 방법이면 충분하리라고 생각합니다. 세째, RandomAccessFile을 받아서 현재 위치부터 read/write하는 Stream 객체를 하나 만듭니다. 파일에 쓰는 경우는 OutputStream을 상속해서 RandomAccessOutputStream 정도의 클래스를 하나 만들어서 OutputStreamWriter가 주는 내용을 RandomAccessFile의 메쏘드를 이용해서 파일에다가 써 주면 됩니다. 두번재 방법이면 충분할 것이므로 더이상 설명을 않도록 하겠습니다. 흥미가 있으시면 세번째 방법도 시도해 보십시오. 좀 더 일반적인 방법이므로 파일이 아닌 다른 경우에도 응용이 가능합니다. -------------------------------------------------------------------------- Mon, 22 Dec 1997 13:42:38 han.comp.lang.java Thread 815 of 843 Lines 16 Re: 파일에서 특정 문자열을 찾고 그 위 RespNo 1 of 1 dynaxis@ivory.kaist.ac.kr Kim Do-Hyung at PL lab., CSD, KAIST 성 시 완 <s_orion1@hanbat.chungnam.ac.kr> wrote: : 파일에서 특정 문자열의 정확한 위치를 알고 싶을 때, 어떻게 해야 될지 : 모르겠군요. RandomAccessFile에서 seek()를 쓰면 이것은 어떤 특정 위치 : 만 찾아주지 어떤 특정 문자열이나 데이터가 저장되어 있는 정확한 위치 : 는 모릅니다. 누가 이 방법을 아는 사람있으면 꼭 좀 답해주세요. : 감사합니다. 당연히 읽어가면서 찾아야 하지 않겠습니까? 검색까지 자동으로 해 주는 API는 없습니다. ^^; Perl같이 문자열 처리에 탁월한 스크립트 같은 언어라면 몰라도 자바 관점에서는 너무 고수준의 API라고 생각되는군요. 이런 경우라면 RandomAccessFile을 쓸 것도 없이 파일을 InputStream혹은 Reader로 열어서 읽어가면서 내용을 찾으면서, 동시에 다른 파일을 하나 더 열어서 안 바뀔 부분은 그냥 적어주고, 바뀔 부분은 원래 내용대신 바뀐 내용을 넣어주면 되겠군요. |