문제

자주 업데이트되는(분당 약 20~30회) .csv 파일이 있습니다.새로 추가된 라인을 파일에 기록하자마자 데이터베이스에 삽입하고 싶습니다.

그만큼 파일 시스템 감시자 클래스는 파일 시스템 변경 알림을 수신하고 지정된 파일에 변경이 있을 때마다 이벤트를 발생시킬 수 있습니다.문제는 FileSystemWatcher가 정확히 어떤 줄이 추가되거나 제거되었는지 확인할 수 없다는 것입니다(내가 아는 한).

해당 줄을 읽는 한 가지 방법은 변경 사항 간의 줄 수를 저장하고 비교하고 마지막 변경 사항과 두 번째 마지막 변경 사항 간의 차이를 읽는 것입니다.그러나 저는 더 깔끔한(아마도 더 우아한) 솔루션을 찾고 있습니다.

도움이 되었습니까?

해결책

나는 매우 비슷한 것을 썼습니다.FileSystemWatcher를 사용하여 변경 사항에 대한 알림을 받았습니다.그런 다음 FileStream을 사용하여 데이터를 읽었습니다(파일 내의 마지막 위치를 추적하고 새 데이터를 읽기 전에 해당 위치를 찾습니다).그런 다음 자동으로 전체 라인을 추출한 다음 UI에 출력하는 버퍼에 읽은 데이터를 추가합니다.

메모:"this.MoreData(..)는 리스너가 앞서 언급한 버퍼에 추가하고 전체 라인 추출을 처리하는 이벤트입니다.

메모:이미 언급했듯이 이는 수정 사항이 항상 파일에 추가되는 경우에만 작동합니다.삭제하면 문제가 발생합니다.

도움이 되었기를 바랍니다.

   public void File_Changed( object source, FileSystemEventArgs e )
    {
        lock ( this )
        {
            if ( !this.bPaused )
            {
                bool bMoreData = false;

                // Read from current seek position to end of file
                byte[] bytesRead = new byte[this.iMaxBytes];
                FileStream fs = new FileStream( this.strFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );

                if ( 0 == this.iPreviousSeekPos )
                {
                    if ( this.bReadFromStart )
                    {
                        if ( null != this.BeginReadStart )
                        {
                            this.BeginReadStart( null, null );
                        }
                        this.bReadingFromStart = true;
                    }
                    else
                    {
                        if ( fs.Length > this.iMaxBytes )
                        {
                            this.iPreviousSeekPos = fs.Length - this.iMaxBytes;
                        }
                    }
                }

                this.iPreviousSeekPos = (int)fs.Seek( this.iPreviousSeekPos, SeekOrigin.Begin );
                int iNumBytes = fs.Read( bytesRead, 0, this.iMaxBytes );
                this.iPreviousSeekPos += iNumBytes;

                // If we haven't read all the data, then raise another event
                if ( this.iPreviousSeekPos < fs.Length )
                {
                    bMoreData = true;
                }

                fs.Close();

                string strData = this.encoding.GetString( bytesRead );
                this.MoreData( this, strData );

                if ( bMoreData )
                {
                    File_Changed( null, null );
                }
                else
                {
                    if ( this.bReadingFromStart )
                    {
                        this.bReadingFromStart = false;
                        if ( null != this.EndReadStart )
                        {
                            this.EndReadStart( null, null );
                        }
                    }
                }
            }
        }

다른 팁

맞습니다. FileSystemWatcher는 파일 내용에 대해 아무것도 모릅니다.변경되었는지 등을 알려드립니다.하지만 무엇이 바뀌었는지는 아닙니다.

파일에만 추가하고 있습니까?줄이 추가되었는지 아니면 제거될 수도 있는지가 게시물에서 약간 불분명했습니다.추가되었다고 가정하면 솔루션은 매우 간단합니다. 그렇지 않으면 몇 가지 비교를 수행하게 됩니다.

NTFS Change Journal 또는 이와 유사한 것을 사용해야 한다고 생각합니다.

Change Journal은 NTFS에 의해 볼륨의 파일에 대한 모든 변경 사항을 지속적으로 로그를 제공하기 위해 사용됩니다.각 책에 대해 NTFS는 Change Journal을 사용합니다. 추가, 삭제 및 수정 된 파일에 대한 정보 추적.Change Journal은 주어진 네임 스페이스의 변경 사항을 결정하기위한 타임 스탬프 또는 파일 알림보다 훨씬 효율적입니다.

당신은 찾을 수 있습니다 TechNet에 대한 설명..NET에서 PInvoke를 사용해야 합니다.

현재 텍스트가 충분히 작으면 메모리에 유지한 다음 diff 알고리즘을 사용하여 새 텍스트와 이전 텍스트가 변경되었는지 확인합니다.이 도서관은, http://www.mathertel.de/Diff/, 변경된 사항뿐만 아니라 변경된 사항도 알려줍니다.그러면 변경된 데이터를 db에 삽입할 수 있습니다.

내 머리 꼭대기에서 마지막으로 알려진 파일 크기를 저장할 수 있습니다.파일 크기를 확인하고 변경되면 리더를 엽니다.

그런 다음 독자에게 마지막 파일 크기를 찾아 거기부터 읽기 시작하세요.

FileSystemWatcher에 대한 당신 말이 맞습니다.생성, 수정, 삭제 등을 들을 수 있습니다.이벤트를 발생시킨 파일보다 더 깊이 들어가지는 않습니다.

파일 자체를 제어할 수 있나요?파일을 버퍼처럼 사용하기 위해 모델을 약간 변경할 수 있습니다.하나의 파일 대신 두 개가 있습니다.하나는 스테이징이고, 하나는 처리된 모든 출력의 합계입니다."버퍼" 파일에서 모든 줄을 읽고 처리한 다음 처리된 모든 줄의 합계인 다른 파일의 끝에 삽입합니다.그런 다음 처리한 줄을 삭제합니다.이렇게 하면 파일의 모든 정보가 처리 보류됩니다.문제는 시스템이 쓰기 이외의 다른 것(예:줄도 삭제함) 그러면 작동하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top