¿Cómo leer continuamente imágenes de la carpeta de origen?

programación


Mi programa consta de los siguientes pasos:
1. leer cualquier imagen nueva de una carpeta de origen
2. procesar imagen (detectar objetos y alinearlos)
3. guarde las imágenes de objetos alineadas en una carpeta de destino
…repetir

La idea es que mientras escanea sellos, el programa genere cada sello individualmente o agrupado si los sellos están agrupados. El usuario debería poder realizar escaneos continuamente mientras se procesan.

El programa se comporta de tres maneras distintas, basándose en tres formas de detectar nuevas imágenes en la carpeta de destino. En la práctica sólo se utilizará la tercera vía. Es de esperar que los dos primeros puedan ayudar a explicar qué está sucediendo y por qué.

1. Arrastrar y soltar
Todo funciona bien cuando se arrastra y suelta una imagen en la carpeta manualmente; Puedo hacer esto indefinidamente y los resultados son correctos.

2. Copiar y pegar
Al copiar y pegar una imagen localmente en la carpeta de destino, el programa se detiene inmediatamente y muestra la siguiente excepción:

System.IO.IOException: 'Unable to access the file xxx because it is being used by another process.'

Esta misma excepción ocurre al copiar y pegar imágenes dentro de la carpeta de destino.

3. Salida del programa de escaneo
Utilizo el ScanSnap SV600, que guarda escaneos de sellos sin procesar en la carpeta de destino. Ahora viene el caso que me desconcierta: mi programa de procesamiento alterna en su comportamiento. El primer escaneo siempre tiene éxito cada vez que inicio el programa en modo de depuración. Pero la lectura en el análisis posterior dentro de esa misma ejecución del programa de procesamiento falla en el caso de que la sesión de depuración anterior haya tenido éxito. En otras palabras: una de cada dos veces el programa se comporta como se desea. Y las otras veces se detiene en el segundo escaneo, dándome el error anterior.

Para detectar nuevas imágenes utilizo:

C#
var fileSystemWatcher = new FileSystemWatcher(@inputDir)
{
    Filter = "*.jpg",
    NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
    EnableRaisingEvents = true
};
fileSystemWatcher.Created += new FileSystemEventHandler(OnFileCreated);

Lo que he probado:

Además, esto es parte del código antes de que comience el procesamiento. No es el más hermoso y se siente un poco “truco” al usar `Thread.Sleep()`. ¿Quizás aquí haya una pista?

C#
private void OnFileCreated(object sender, FileSystemEventArgs e)
{
    sw.Restart();
    string imagePath = e.FullPath;
    inputFiles.AddToQ(imagePath);
    Console.WriteLine("{0} is queued.", e.FullPath);

    int number = 0;
    if (!int.TryParse(setCluster.Text.Trim(), out number))
    {
        MessageBox.Show("Please enter a valid number for Clustering.");
        setCluster.Text = "20";
    }
    else
    {
        while (inputFiles.Inspect() != imagePath) Thread.Sleep(100);
        try
        {
            lock (locker)
            {
                Bitmap incoming = new Bitmap(inputFiles.Process());
                Console.WriteLine("{0} is being processed.", e.FullPath);

                if (currentScan.Image != null) currentScan.Image = null;
                currentScan.Invoke((Action)
                delegate ()
                {
                    currentScan.Image = (Image)new Bitmap(e.FullPath);
                    currPathText.Text = imagePath;
                });

                // processing step
                Bitmap resized = new Bitmap(incoming, new
                    Size(Convert.ToInt32(incoming.Width / Variables.ScalingFact),
                    Convert.ToInt32(incoming.Height / Variables.ScalingFact)));
                .....

Solución 1

Esto es simple. Está intentando leer el archivo antes de que se complete el proceso de copia y se cierre el archivo.

Sólo tienes que INTENTAR abrir el archivo. Si arroja una excepción porque ya está en uso, espere un poco y vuelva a intentarlo. Continúe intentándolo hasta que abra el archivo o agote el límite de reintentos que elija arbitrariamente.

コメント

タイトルとURLをコピーしました