2010-09-28 41 views
13

Tengo un archivo que contiene los datos que me gustaría para monitorear los cambios a, así como añadir cambios de mi propia. Piensa como "Tail -f foo.txt".lectura y escritura simultánea un archivo en C#

Basado en this thread, parece que debería crear una secuencia de archivos y pasarla a un escritor y lector. Sin embargo, cuando el lector llega al final del archivo original, no puede ver las actualizaciones que yo mismo escribo.

Yo sé que parece una situación extraña ... es más un experimento para ver si se puede hacer.

Aquí es el caso del ejemplo I intentado:


foo.txt:
un
b
c
d
e
f


 string test = "foo.txt"; 
     System.IO.FileStream fs = new System.IO.FileStream(test, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite); 

     var sw = new System.IO.StreamWriter(fs); 
     var sr = new System.IO.StreamReader(fs); 

     var res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     sw.WriteLine("g"); 
     sw.Flush(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     sw.WriteLine("h"); 
     sw.Flush(); 
     sw.WriteLine("i"); 
     sw.Flush(); 
     sw.WriteLine("j"); 
     sw.Flush(); 
     sw.WriteLine("k"); 
     sw.Flush(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 
     res = sr.ReadLine(); 

Después de pasar la "f", el lector devuelve nulo.

+0

Un póster puso algo sobre tener dos secuencias de archivos apuntando al mismo objeto ... que funcionó.Incluso si el lector llega al final del archivo, si el escritor se actualiza, la secuencia de lectura obtiene ambos resultados. – tbischel

+0

Sí, ese soy yo borrando mi publicación después de que no funcionó como esperaba. Lo restauré con una explicación de por qué ... – MarkPflug

Respuesta

20

Ok, dos ediciones más tarde ...

esto debería funcionar. La primera vez que lo intenté, creo que olvidé configurar FileMode.Append en el oStream.

string test = "foo.txt"; 

var oStream = new FileStream(test, FileMode.Append, FileAccess.Write, FileShare.Read); 
var iStream = new FileStream(test, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

var sw = new System.IO.StreamWriter(oStream); 
var sr = new System.IO.StreamReader(iStream); 
var res = sr.ReadLine(); 
res = sr.ReadLine(); 
sw.WriteLine("g"); 
sw.Flush(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
sw.WriteLine("h"); sw.Flush(); 
sw.WriteLine("i"); sw.Flush(); 
sw.WriteLine("j"); sw.Flush(); 
sw.WriteLine("k"); sw.Flush(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
+0

Seleccioné FileShare.ReadWrite de oStream. – Mehmet

1

Si se agrega una llamada a StreamReader.DiscardBufferedData(), ¿cambia el comportamiento?

+0

esto hizo que las lecturas de la secuencia se vuelvan nulas tan pronto como lo llamo. – tbischel

3

creo que cada vez que se escribe un carácter, que están avanzando la posición corriente, por lo que los próximos intentos de lectura para leer después del carácter que acaba de escribir. Esto sucede porque su lector de flujo y escritor de flujo están usando el mismo FileStream. Utilice una secuencia de archivos diferente, o busque -1 caracteres en la secuencia después de cada escritura.

+0

así la forma en que entrelazo las escrituras y lecturas fue para ver si este era el caso. El lector todavía lee correctamente en orden, simplemente no ve ningún nuevo dato agregado por el escritor. – tbischel

2

Es muy poco probable que le satisfaga cualquier solución a este problema que implique utilizar la misma secuencia de lectura y escritura. Esto es especialmente cierto si intenta leer la cola del archivo con un StreamReader.

Desea tener dos secuencias de archivos diferentes. La secuencia de escritura puede ser StreamWriter si lo desea. La secuencia de lectura debe ser una secuencia binaria (es decir, crear con File.OpenRead o FileStream.Create), leer los bytes sin formato del archivo y convertir a texto. Mi respuesta al this question muestra los conceptos básicos de cómo se hace.

9

@mikerobi es correcto, cuando escribe en la secuencia, el puntero del archivo se cambia y se mueve al final de la secuencia. Con lo que no se puede contar es que StreamReader tiene su propio buffer. Lee 1024 bytes del archivo y obtendrás resultados de ese búfer. Hasta que se agote el búfer, debe volver a leer FileStream. No se encuentra nada porque el puntero al archivo se encuentra al final del archivo.

Realmente necesita separar FileStreams, cada uno con su propio puntero de archivo para tener alguna esperanza de que esto funcione.

+0

Gracias Hans, estaba buscando confirmar este hecho al tratar de desarrollar una solución yo mismo. Fue útil ver que parece llegar a la misma conclusión. – jpierson

Cuestiones relacionadas