c# - ejemplo - Sistema de archivos vigilante y archivos de gran tamaño
filesystemwatcher windows service c# (5)
AFAIK no se notifica una vez que la copia está hecha, puede implementar un mecanismo de reintento.
Si obtiene una violación por cizalla, active un temporizador para volver a intentar la operación en X segundos.
El segundo intento debe ser después de X * 2 segundos y así sucesivamente (con alguna limitación de curso).
var fsw = new FileSystemWatcher(sPath, "*.PPF");
fsw.NotifyFilter = NotifyFilters.FileName;
fsw.IncludeSubdirectories = true;
fsw.Created += FswCreated;
fsw.EnableRaisingEvents = true;
static void FswCreated(object sender, FileSystemEventArgs e)
{
string sFile = e.FullPath;
string[] arrLines = File.ReadAllLines(sFile);
}
esto falla con archivos grandes, porque el proceso no está terminado con la escritura del archivo. El archivo se copia a través de la red, por lo que no sé el tamaño del archivo. ¿Qué tipo de sincronización se requiere para que esto sea sólido?
Apoyo la solución aceptada por Shay Erlichmen. Pero sin embargo a) Usted puede querer abrir el archivo con el modo de acceso FileAccess.Read, en caso de que sea un archivo de solo lectura
b) Algunos programas durante la descarga, el archivo tendrá una extensión divertida y cuando se complete, la extensión cambiará, y aunque el archivo se habrá completado, no tendrá una excepción de archivo no encontrado.
Así que maneje las excepciones y también suscríbase al evento file.renamed
Simplemente en su fswCreated
, duerma aproximadamente 1/2 segundo con Thread.Sleep(500)
si eso es posible. Eso debería darle el tiempo que la computadora necesita para terminar de escribir el archivo.
Por supuesto, para discos duros más lentos, esto puede o puede ser suficiente.
Solución encontrada en y modificada un poco.
static bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open,
FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
static void FswCreated(object sender, FileSystemEventArgs e)
{
string sFile = e.FullPath;
Console.WriteLine("processing file : " + sFile);
// Wait if file is still open
FileInfo fileInfo = new FileInfo(sFile);
while(IsFileLocked(fileInfo))
{
Thread.Sleep(500);
}
string[] arrLines = File.ReadAllLines(sFile);
}
Utilice la clase DelayedFileSystemWatcher.cs
http://blogs.msdn.com/b/ahamza/archive/2006/02/06/526222.aspx
y luego este código Compruebe el PrintFileSystemEventHandler
eventos PrintFileSystemEventHandler. Intenta leer el archivo en la secuencia de archivos y, si se produce algún error, asume que el archivo todavía está leyendo, por lo que espera un intervalo (2 segundos en este ejemplo) y luego vuelve a intentarlo. Verifique la CONVERSION:
etiqueta
static void Main(string[] args)
{
DelayedFileSystemWatcher dfw = new DelayedFileSystemWatcher(@"C://Test", "*.*");
dfw.Changed += new FileSystemEventHandler(Program.FileSystemEventHandlerMethod);
dfw.Created += new FileSystemEventHandler(Program.FileSystemEventHandlerMethod);
dfw.Deleted += new FileSystemEventHandler(Program.FileSystemEventHandlerMethod);
dfw.Error += new ErrorEventHandler(Program.ErrorEventHandlerMethod);
dfw.Renamed += new RenamedEventHandler(Program.RenamedEventHandlerMethod);
dfw.IncludeSubdirectories = true;
dfw.ConsolidationInterval = 1000;
dfw.EnableRaisingEvents = true;
Console.WriteLine("Press /'q/' to quit the sample.");
while (Console.Read() != ''q'') ;
//System.Threading.Thread.Sleep(60000);
dfw.Dispose();
}
private static void FileSystemEventHandlerMethod(object sender, FileSystemEventArgs e)
{
PrintFileSystemEventHandler(e);
System.Console.WriteLine();
}
private static void ErrorEventHandlerMethod(object sender, ErrorEventArgs e)
{
System.Console.WriteLine(e.GetException().Message);
System.Console.WriteLine();
}
private static void RenamedEventHandlerMethod(object sender, RenamedEventArgs e)
{
PrintRenamedEventHandler(e);
System.Console.WriteLine();
}
private static void PrintFileSystemEventHandler(FileSystemEventArgs e)
{
CONVERSION:
try
{
if (e.ChangeType != WatcherChangeTypes.Deleted)
{
if (!isFolder(e.FullPath) && isFile(e.FullPath))
{
FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.None);
fs.Close();
}
}
System.Console.WriteLine(e.Name + " " + e.FullPath + " " + e.ChangeType);
}
catch (System.IO.IOException)
{
Console.WriteLine("There was an IOException error or File is still copying. Retrying in 2 seconds...");
System.Threading.Thread.Sleep(2000);
goto CONVERSION;
}
//System.Console.WriteLine(e.Name);
//System.Console.WriteLine(e.FullPath);
//System.Console.WriteLine(e.ChangeType);
}
private static bool isFolder(string strPath)
{
bool isFolderExist = false;
try
{
isFolderExist = Directory.Exists(strPath);
}
catch
{
isFolderExist = false;
}
return isFolderExist;
}
private static bool isFile(string strPath)
{
bool isFileExist = false;
try
{
isFileExist = File.Exists(strPath);
}
catch
{
isFileExist = false;
}
return isFileExist;
}
private static void PrintRenamedEventHandler(RenamedEventArgs e)
{
PrintFileSystemEventHandler(e);
System.Console.WriteLine(e.OldName);
System.Console.WriteLine(e.OldFullPath);
}
No tengo el enlace al proyecto. pero esto ayudará.