2008-11-14 7 views
23

텍스트 파일을 편집하는 간단한 프로그램 (Java로)을 만들고 싶습니다. 특히 텍스트 파일의 임의 위치에 임의의 텍스트를 삽입하는 프로그램을 만들고 싶습니다. 이 기능은 내가 현재 작성중인 더 큰 프로그램의 일부입니다.자바를 통해 기존 파일에 텍스트 삽입하기

java.util.RandomAccessFile에 대한 설명을 읽으면 파일 중간에서 수행 된 모든 쓰기 작업이 실제로 종료 된 내용을 덮어 쓰는 것으로 나타납니다. 이것은 (가능한 경우) 피하고 싶은 부작용입니다.

간단한 방법이 있나요?

미리 감사드립니다.

+4

을,이 자바 단지 제한하지 않습니다. 이것은 모든 I/O가 작동하는 방식입니다. 기본 OS가 제공하는 기능입니다. –

+3

아마 파일의 중간에 빠른 데이터 삽입을 허용 할 수있는 연결 목록 데이터 블록과 같은 것을 지원하는 파일 시스템 구현이 있습니다. 그러나 이것을 달성하기 위해서는 꽤 낮은 수준의 시스템 호출이 필요합니다. –

+1

정확한 기사를 찾을 수 없지만 간단한 텍스트 편집기를 구동하는 데이터 구조로 로프를 사용하는 방법을 설명하는 기사를 읽었습니다. http://en.wikipedia.org/wiki/Rope_%28computer_science%29 – Albert

답변

15

좋아,이 질문은 꽤 오래지만, FileChannels 자바 1.4부터 존재의 문제를 다룰 때 그들은 어디서나 언급되지 않은 이유를 모르겠어요 파일의 내용 바꾸기 또는 삽입하기. FileChannels이 빠르면 사용하십시오.

여기 예입니다 (예외 및 다른 물건을 무시) : 당신이 이해 너무

public void insert(String filename, long offset, byte[] content) { 
    RandomAccessFile r = new RandomAccessFile(new File(filename), "rw"); 
    RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw"); 
    long fileSize = r.length(); 
    FileChannel sourceChannel = r.getChannel(); 
    FileChannel targetChannel = rtemp.getChannel(); 
    sourceChannel.transferTo(offset, (fileSize - offset), targetChannel); 
    sourceChannel.truncate(offset); 
    r.seek(offset); 
    r.write(content); 
    long newOffset = r.getFilePointer(); 
    targetChannel.position(0L); 
    sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset)); 
    sourceChannel.close(); 
    targetChannel.close(); 
} 
+0

FileChannel을 사용하여 이미지에 텍스트를 오버레이 할 수 있습니까? – NPE

+0

일반적으로 FileChannels를 사용하여 원하는대로 모든 종류의 파일을 수정할 수 있습니다. 그러나 문제는 내가 상상할 수있는 모든 용도로 파일에 쓸 내용을 알아야한다는 것입니다. 이미지가 .SVG 인 경우 FileChannel을 사용하여 필요한 xml-Element를 파일에 쓸 수 있습니다. 그러나 귀하의 질문이 구체적이지 않았기 때문에 대답은 "아니오, 당신이하고있는 일을 모르기 때문입니다." . java.awt.Image 클래스, 특히 BufferedImage 클래스를 살펴보고 적절하게 튜토리얼을 읽고 거기에서 시작할 수 있습니다. –

+0

그래, 몇 가지 조사를 한 후에. 나는 FileChannel 대신에'Graphic' 객체를 사용합니다. – NPE

2

기존 텍스트 파일에 텍스트를 삽입하는 유일한 방법은 원본 파일을 읽고 새 텍스트가 삽입 된 임시 파일에 내용을 쓰는 것입니다. 그런 다음 원본 파일을 지우고 임시 파일의 이름을 원래 이름으로 바꿉니다.

example은 기존 파일에 한 줄을 삽입하는 데 중점을두고 있지만 여전히 유용 할 수 있습니다.

2

내가 거기에 그것을 할 수있는 편리한 방법이 바로 그렇지 않으면

  • 이외의 파일의 시작 부분을 읽으면 알고
  • 읽기를 목표로 새 텍스트를 작성 대상을 쓰지 않는다 파일의 나머지 부분을 대상으로 작성하십시오.

대상 : 메모리에 파일의 새 내용을 구성한 다음 처리 된 파일이 너무 크지 않은 경우 파일의 이전 내용을 덮어 쓸 수 있습니다. 또는 결과를 임시 파일에 쓸 수 있습니다.

아마 스트림과 함께하는 것이 가장 쉽습니다. RandomAccessFile은 중간에 삽입하는 것이 아닙니다 (afaik). 필요한 경우 tutorial을 확인하십시오.

11

글쎄, 아니, 나는 기존의 컨텐트를 하나의 표준 Java IO API 호출로 덮어 쓰지 않는 방법이 있다고 생각하지 않는다.

파일이 너무 크지 않은 경우 전체 파일을 ArrayList (행당 항목)로 읽고 항목을 다시 쓰거나 새 줄을 삽입하십시오.

그런 다음 기존 파일을 새 콘텐츠로 덮어 쓰거나 기존 파일을 백업으로 이동하고 새 파일을 작성하십시오.

편집의 정교함에 따라 데이터 구조가 변경되어야 할 수도 있습니다.

다른 방법은 편집 된 파일에 쓰는 동안 기존 파일에서 문자를 읽고 스트림을 읽을 때 편집하는 것입니다.

3

Java에 메모리 맵 파일을 저장하는 방법이 있다면, 파일을 새로운 길이로 확장하고, 파일을 매핑하고, 모든 바이트를 끝까지 memmove하여 구멍을 만들고 새 데이터를 쓸 수 있습니다. 구멍.

이것은 C에서 작동합니다. 결코 Java로 시도하지 않았습니다.

난 그냥 같은 일을 할 생각하지만 다른 임의의 파일 액세스.

  • 끝까지 탐색 - 1메가바이트
  • 읽기 1메가바이트
  • 쓰기를 원래의 위치 + 갭 크기.
  • 이전 1MB마다 파일 시작 부분을 반복합니다.
  • 원하는 간격 위치에 도달하면 중지하십시오.

빠른 성능을 위해 더 큰 버퍼 크기를 사용하십시오.

0

텍스트 파일 인 경우, StringBuffer의 기존 파일을 읽고 동일한 내용의 StringBuffer에 새 내용을 추가하면 파일에 SrtingBuffer를 쓸 수 있습니다. 이제 파일에는 기존 텍스트와 새 텍스트가 모두 포함됩니다.

4

당신은 다음과 같은 코드를 사용할 수 있습니다

BufferedReader reader = null; 
BufferedWriter writer = null; 
ArrayList list = new ArrayList(); 

try { 
    reader = new BufferedReader(new FileReader(fileName)); 
    String tmp; 
    while ((tmp = reader.readLine()) != null) 
     list.add(tmp); 
    OUtil.closeReader(reader); 

    list.add(0, "Start Text"); 
    list.add("End Text"); 

    writer = new BufferedWriter(new FileWriter(fileName)); 
    for (int i = 0; i < list.size(); i++) 
     writer.write(list.get(i) + "\r\n"); 
} catch (Exception e) { 
    e.printStackTrace(); 
} finally { 
    OUtil.closeReader(reader); 
    OUtil.closeWriter(writer); 
} 
관련 문제