2010-12-04 3 views
5

나는 하나의 csv 파일을 가지고 있는데, 이것은 스크립트에 의해 연속적으로 쓰여지고있다. 타임 스탬프와 행당 다른 데이터를 씁니다. 나는 최신 자료를 먼저 읽어야한다. 현재 Java에서 RandomAccessFile을 사용하여 파일을 역순으로 읽습니다. 그러나 계속 쓰여진 것처럼 새로운 데이터를 우선적으로 읽어야합니다. 어떤 타임 스탬프를 보냈는지와 작업하고 있습니다. 불필요한 스캐닝 작업이 발생합니다.내 접근 방식에 대한 제안이 필요합니다. 연속적으로 쓰여지고있는 파일을 읽으려면?

이 시나리오를 처리하는 더 좋은 방법이 있습니까? 사전에

감사합니다,

답변

1

당신은 하나 개가 나타나는 새로운 라인을 읽고 처리되지 않은 행의 스택에 그들을 밀어 스레드 스택으로 나타나고 역으로 새로운 행을 처리하는 두 번째 스레드를 가진 고려할 수 주문.

새 행을 생성하는 데 걸리는 시간과 생성되는 행의 처리 속도에 따라 충분할 수 있습니다. 새 행을 처리하는 것보다 빠르게 생성하면이 방법이 효과가 없을 것입니다. 스택이 너무 커져 메모리가 부족합니다. 이 경우 요구 사항에 따라 오래된 항목을 삭제하는 크기 제한 스택을 제거 할 수 있습니다.

1

두 아이디어 :

  1. 대신 CSV의 고정 된 크기의 레코드 형식을 사용합니다. 그런 다음 줄 바꿈을 찾아 다니는 대신에 레코드가있는 오프셋을 정확히 알 수 있습니다.

  2. 그럴 수 없다면 파일에서 항목을 읽고이를 스택으로 푸시하십시오. 다른 스레드는 스택에서 항목을 팝하고 처리합니다. 스택이므로 항상 가장 최근에 사용 가능한 항목을 처리합니다. 스택이 너무 커지면 어떻게 대처해야하는지 알아야합니다. 너무 오래된 물건을 버리시겠습니까?

0

원본 스크립트에 액세스 할 수있는 경우 CSV 파일 외에 데이터베이스에 레코드를 씁니다. 그런 다음 데이터베이스로 원하는 모든 작업을 수행 할 수 있습니다. 마지막 레코드 액세스, 보고서 실행, 등등.

0

이로 인해 불필요한 검색 작업이 발생합니다.

나는 어떤 포인트를 찾고 다음 새 줄 바꿈이 나올 때까지 읽음으로써 다음 유효한 CSV 행 시작 위치를 찾는다고 가정합니다.

  1. 는 전체 파일을 읽고 전달 방향으로 행을 구문 분석, 메모리의 위치를 ​​저장 : 현재 무엇을하고 있는지 나는보다 더 효율적으로 될 수 있음을이 작업을 수행하는 세 가지 방법의

    을 생각할 수 . 그런 다음 메모리 내 행을 역순으로 처리합니다.

  2. 행 시작을 찾기 위해 처음부터 파일을 스캔하고 행 시작 위치를 메모리에 저장하십시오. 그런 다음 역순으로 위치를 반복하면서 각 행을 찾아 해당 행을 읽습니다. (각 탐색에서 여러 행을 처리하여 입력을보다 효율적으로 수행 할 수 있습니다.)

  3. MappedByteBuffer을 사용하여 파일을 메모리에 매핑하면 Byte 버퍼를 앞뒤로 이동하여 행 경계를 찾을 수 있습니다.

첫 번째 방법

는 메모리에 전체 파일을 버퍼링 할 수 있어야하지만 시스템 호출 최소한으로 한 번만 파일을 읽을 수 있기 때문에 낮은 I/O 오버 헤드가 있습니다. 세 번째 접근법은 똑같은 문제가 있습니다. 메모리 요구 사항을 줄이기 위해 매우 큰 파일을 (큰) 섹션의 메모리로 매핑 할 수도 있습니다.

하지만 궁극적으로 Java에서 파일을 거꾸로 읽는 방법은 없습니다. 응용 프로그램이 유닉스 환경에서 실행중인 경우

0

, 당신은 단순히 표준 입력을 수락하고 자바 프로그램으로 소켓 연결에 그 반향 것

tail -f /csv-file | custom-program 

맞춤 프로그램을 실행할 수 있습니다.

Java 프로그램이 명령 줄에서 시작할 수없는 일종의 서버 응용 프로그램이라고 가정합니다. 그게 실제로 괜찮다면, 사용자 정의 프로그램을 Java 프로그램으로 대체 할 수 있습니다.

관련 문제