2010-03-03 19 views
9

In Linux, un sacco di IPC viene eseguito aggiungendo un file in 1 processo e leggendo il nuovo contenuto da un altro processo.Leggere le modifiche del contenuto del file in .NET

Voglio fare quanto sopra in Windows/.NET (troppo disordinato per usare normali IPC come pipe). Sto accodando a un file da un processo Python, e voglio leggere le modifiche e SOLO le modifiche ogni volta che FileSystemWatcher segnala un evento. Non voglio leggere l'intero contenuto del file in memoria ogni volta che cerco modifiche (il file sarà enorme)

Ogni operazione di aggiunta aggiunge una riga di dati che inizia con un contatore incrementale univoco (timestamp + tasto) e termina con una nuova riga.

risposta

25
using (FileStream fs = new FileStream 
     (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
    { 
     using (StreamReader sr = new StreamReader(fs)) 
     { 
      while (someCondition) 
      { 
       while (!sr.EndOfStream) 
        ProcessLinr(sr.ReadLine()); 
       while (sr.EndOfStream) 
        Thread.Sleep(100); 
       ProcessLinr(sr.ReadLine());    
      } 
     } 
    } 

questo vi aiuterà a leggere le linee solo allegati

+0

testato, funziona. Tecnica abbastanza bella. –

+0

UNA GRANDE soluzione, breve e letale! – MaYaN

9

È possibile memorizzare l'offset dell'ultima operazione di lettura e cercare il file che compensati quando si ottiene una notifica di file modificato. Segue un esempio:

metodo Main:

public static void Main(string[] args) 
{ 
    File.WriteAllLines("test.txt", new string[] { }); 

    new Thread(() => ReadFromFile()).Start(); 

    WriteToFile(); 
} 

Leggi dal metodo del file:

private static void ReadFromFile() 
{ 
    long offset = 0; 

    FileSystemWatcher fsw = new FileSystemWatcher 
    { 
     Path = Environment.CurrentDirectory, 
     Filter = "test.txt" 
    }; 

    FileStream file = File.Open(
     "test.txt", 
     FileMode.Open, 
     FileAccess.Read, 
     FileShare.Write); 

    StreamReader reader = new StreamReader(file); 
    while (true) 
    { 
     fsw.WaitForChanged(WatcherChangeTypes.Changed); 

     file.Seek(offset, SeekOrigin.Begin); 
     if (!reader.EndOfStream) 
     { 
      do 
      { 
       Console.WriteLine(reader.ReadLine()); 
      } while (!reader.EndOfStream); 

      offset = file.Position; 
     } 
    } 
} 

scrivere sul file metodo:

private static void WriteToFile() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     FileStream writeFile = File.Open(
      "test.txt", 
      FileMode.Append, 
      FileAccess.Write, 
      FileShare.Read); 

     using (FileStream file = writeFile) 
     { 
      using (StreamWriter sw = new StreamWriter(file)) 
      { 
       sw.WriteLine(i); 
       Thread.Sleep(100); 
      } 
     } 
    } 
} 
+0

Sono un po 'un noob quando si tratta di operazioni sui file. Cerca di caricare tutto in memoria o carica solo da offset a offset + lunghezza? – jameszhao00

+0

Per quanto ne so, l'operazione di ricerca non caricherà alcun dato e basterà posizionare il flusso di file nella posizione specificata. In questo caso la posizione sarà dove iniziano i nuovi dati. –

Problemi correlati