2013-06-04 17 views
9

Sto sviluppando uno strumento C# per leggere 8 gb di dati esadecimali da una scheda SD non formattata.FileNotFoundException Gettato a caso

È in grado di farlo, ma genera casualmente Eccezione non trovata file. Ad esempio, leggerà un gigabyte o due, quindi lo lancerà. Altre volte leggerà tutte le 8 gb un paio di volte di fila, quindi lancia l'eccezione. In altre parole, sembra apparire in modo completamente casuale.

Non ho idea di cosa potrebbe causarlo.

EDIT: Ho utilizzato il feedback per modificare alcune cose. Ciò che è incollato sotto è il codice aggiornato.

Getta ancora casualmente la definizione di filiferfoundception, ma ora SEMPRE genera un'eccezione di argomento quando tenta di leggere mb 432 di gig 8 (se arriva così lontano senza casualmente lanciare filiferfound).

L'errore si riferisce al fatto che il filehandle non supporta le operazioni sincrone.

class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, 
     uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, 
     uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

    static void Main(string[] args) 
    { 
     string testOutputDirectory = @"C:\\Users\\aiovanna\\Desktop\\out1.txt"; //Specifies where to write the results of the read. 
     try 
     { 
      SafeFileHandle fileHandle = CreateFile("\\\\.\\E:", 0x80000000, 0, IntPtr.Zero, 3, 0, IntPtr.Zero); 
      FileStream readStream = new FileStream(fileHandle, FileAccess.Read); //The stream to be read. Is converted to binary. 
      BufferedStream bufStream = new BufferedStream(readStream, 1048576); 
      FileStream writeStream = File.OpenWrite(testOutputDirectory); //Writing stream opened at the specified directory of output. 
      //BinaryReader reader = new BinaryReader(readStream); //Changes the read stream to binary. Has more powerful methods. 

      long gigsRead; //Loop counter that specifies the number of gigabytes read thus far. 
      long megsRead; //Loop counter that specifies the number of megabytes read thus far within the current gigabyte. 

      Stopwatch totalStopwatch = new Stopwatch(); //Stopwatch to time the total execution of the card read. 
      Stopwatch megStopwatch = new Stopwatch(); //Stopwatch to time the execution of reading the current megabyte. 
      Stopwatch gigStopwatch = new Stopwatch(); //Stopwatch to time the executation of reading the current gigabyte. 
      totalStopwatch.Start(); //Start timing the program. 
      int bytesRead; 

      for (gigsRead = 0; gigsRead < 8; gigsRead++) //Gigabyte loop 
      { 
       gigStopwatch.Start(); //Start timer for current gigabyte. 
       for (megsRead = 0; megsRead < 1024; megsRead++) //Megabyte loop 
       { 
        megStopwatch.Start(); //Start timer for current megabyte. 

        try 
        { 
         byte[] buffer = new byte[1048576]; //Buffer to be read into from card 
         long test = gigsRead * 1073741824 + megsRead * 1048576; 
         bufStream.Position = test; 
         bytesRead = bufStream.Read(buffer, 0, 1048576); //Read from SD card to buffer 
         if (bytesRead < 1048576) 
         { 
          Console.WriteLine("Didn't read whole chunk!"); 
         } 
         writeStream.Write(buffer, 0, 1048576); //Write from buffer to output text file. 
         megStopwatch.Stop(); //Stop timer for current megabyte. 
         Console.WriteLine("Finished mb {0} of gig {1} in {2}", megsRead + 1, gigsRead + 1, megStopwatch.Elapsed); 
         megStopwatch.Reset(); //Reset for next megabyte. 
        } 

        catch (System.IO.FileNotFoundException ex) 
        { 
         System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
         System.Console.WriteLine("Message: {0}", ex.Message); 
         System.Console.WriteLine("Source: {0}", ex.Source); 
         System.Console.WriteLine("Stack Trace: {0}", ex.StackTrace); 
         System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
         System.Console.WriteLine(ex.ToString()); 
         writeStream.Close(); //Close writing stream. 
         //reader.Close(); //Close the binary reader stream. 
         bufStream.Close(); 
         fileHandle.Close(); //Close the SD card file. 
         readStream.Close(); //Close the filestream reader. 
         System.Console.WriteLine("You will need to turn off your computer, take out the card, turn the computer back on, put the SD card back in, and re-run the program."); 
         System.Console.WriteLine("Press any key to terminate."); 
         System.Console.ReadKey(); 
         System.Environment.Exit(1); 
        } 

        catch (System.ArgumentException ex) 
        { 
         System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
         System.Console.WriteLine("Message: {0}", ex.Message); 
         System.Console.WriteLine("Param Name: {0}", ex.ParamName); 
         System.Console.WriteLine("Source: {0}", ex.Source); 
         System.Console.WriteLine("Stack Trace: {0}", ex.StackTrace); 
         System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
         System.Console.WriteLine(ex.ToString()); 
         writeStream.Close(); //Close writing stream. 
         //reader.Close(); //Close the binary reader stream. 
         fileHandle.Close(); //Close the SD card file. 
         readStream.Close(); //Close the filestream reader. 
         System.Console.WriteLine("You will need to turn off your computer, take out the card, turn the computer back on, put the SD card back in, and re-run the program."); 
         System.Console.WriteLine("Press any key to terminate."); 
         System.Console.ReadKey(); 
         System.Environment.Exit(1); 
        } 
       } 
       gigStopwatch.Stop(); //Stop timer for current gigabyte. 
       Console.WriteLine("Finished gig {0} in {1}", gigsRead + 1, gigStopwatch.Elapsed); 
       gigStopwatch.Reset(); //Reset for next gigabyte. 
      } 
      totalStopwatch.Stop(); //Stop total execution timer. 
      Console.WriteLine(totalStopwatch.Elapsed); //Print total execution timer. 
      writeStream.Close(); //Close writing stream. 
      //reader.Close(); //Close the binary reader stream. 
      writeStream.Close(); //Close writing stream. 
      fileHandle.Close(); //Close the SD card file. 
      readStream.Close(); //Close the filestream reader. 
      bufStream.Close(); 
     } 

     catch (System.IO.IsolatedStorage.IsolatedStorageException ex) 
     { 
      System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
      System.Console.WriteLine("Isolated Storage Exception"); 
      System.Console.WriteLine("Data: {0}", ex.Data); 
      System.Console.WriteLine("Help Link: {0}", ex.HelpLink); 
      System.Console.WriteLine("Inner Exception: {0}", ex.InnerException); 
      System.Console.WriteLine("Message: {0}", ex.Message); 
      System.Console.WriteLine("Source: {0}", ex.Source); 
      System.Console.WriteLine("Stack Trace {0}", ex.StackTrace); 
      System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
      Console.ReadKey(); 
     } 

     catch (System.ArgumentException ex) 
     { 
      System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
      System.Console.WriteLine("Argument Exception"); 
      System.Console.WriteLine("Data: {0}", ex.Data); 
      System.Console.WriteLine("Help Link: {0}", ex.HelpLink); 
      System.Console.WriteLine("Inner Exception: {0}", ex.InnerException); 
      System.Console.WriteLine("Message: {0}", ex.Message); 
      System.Console.WriteLine("Param Name: {0}", ex.ParamName); 
      System.Console.WriteLine("Source: {0}", ex.Source); 
      System.Console.WriteLine("Stack Trace {0}", ex.StackTrace); 
      System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
      Console.ReadKey(); 
     } 

     catch (System.IO.DirectoryNotFoundException ex) 
     { 
      System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
      System.Console.WriteLine("Directory Not Found Exception"); 
      System.Console.WriteLine("Data: {0}", ex.Data); 
      System.Console.WriteLine("Help Link: {0}", ex.HelpLink); 
      System.Console.WriteLine("Inner Exception: {0}", ex.InnerException); 
      System.Console.WriteLine("Message: {0}", ex.Message); 
      System.Console.WriteLine("Source: {0}", ex.Source); 
      System.Console.WriteLine("Stack Trace {0}", ex.StackTrace); 
      System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
      System.Console.ReadKey(); 
     } 

     catch (System.ObjectDisposedException ex) 
     { 
      System.Console.WriteLine("The error was: {0}", Marshal.GetLastWin32Error()); 
      System.Console.WriteLine("Object Disposed Exception"); 
      System.Console.WriteLine("Data: {0}", ex.Data); 
      System.Console.WriteLine("Help Link: {0}", ex.HelpLink); 
      System.Console.WriteLine("Inner Exception: {0}", ex.InnerException); 
      System.Console.WriteLine("Message: {0}", ex.Message); 
      System.Console.WriteLine("Object Name {0}", ex.ObjectName); 
      System.Console.WriteLine("Source: {0}", ex.Source); 
      System.Console.WriteLine("Stack Trace {0}", ex.StackTrace); 
      System.Console.WriteLine("Target Site: {0}", ex.TargetSite); 
      Console.ReadKey(); 
     } 
    } 
} 

Qui di seguito ho ri-scritto l'errore che viene mostrato per FileNotFoundException:

Messaggio: Impossibile trovare il file specificato. Fonte: mscorlib dello stack: in System.IO .__ Error.WinIOError (Int32 errorcode, String maybeFullPath) a System.IO.FileStream.ReadCore (Byte di buffer [], Int32 offset, count Int32) a System.IO.FileStream.Read (Byte [] array, offset Int32, Int32 conteggio) a System.IO.BinaryReader.Read (Byte [] tampone, indice Int32, Int32 conteggio) a RawSDAccessTest.Program.Main (String {} args) in C: \ Users \ etc ... alla riga 67 Sito target: Void WinIOError (Int32, System.String) System.IO.FileNotFoundException: Impossibile trova il file specificato. Riga 67 è: reader.Read (buffer, 0, 1048576);

Ciò che trovo davvero strano qui è che il programma è perfettamente OK con la riga 65, che utilizza anche l'oggetto lettore. In qualche modo tra l'esecuzione delle righe 65 e 67, decide che il file non esiste più. Ho buttato l'attesa in mezzo per vedere se ciò avrebbe risolto. Non è stato così.

Qualche idea su cosa potrebbe causarne il rilascio casuale di questa eccezione o su come risolverlo?

EDIT: Process Monitor mostra il seguente

8: 40: 26,1,077157 millions AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: SUCCESSO Offset: 3.228.565,504 mila, Lunghezza: 1.048.576, Bandiere di I/O: Non-cache, Priorità: normale

8: 40: 26,1,745974 millions AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: No such device Offset: 3,229,614,080, Lunghezza: 131.072,/Bandiere I O: non-cache, Priorità: normale

Così in mezzo le letture, il dispositivo cessa di esistere. Ho spostato la creazione e l'eliminazione del file nel ciclo interno, in modo che crei il file ogni volta che tenta di leggerlo. Il problema persiste. Puzza di hardware per me.

MODIFICA 2: ora occasionalmente genera un'eccezione di lettura asincrona.

9: 16: 16,1,129926 millions AM SDCardReadAttempt3.vshost.exe 3752 ReadFile E: Parametro non valido Offset: 7969,1776 milioni, Lunghezza: 1.048.576, Bandiere di I/O: Non-cache, Priorità: Normale

Non lo so come .net funziona in profondità. Forse lo sta facendo in un processo a thread, quando il file non è aperto per essere letto da più thread. Lancerò l'attesa di nuovo lì per vedere se questo elimina questo errore, così posso tornare a quello originale.

+3

Hai provato dando Process Monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) un colpo per vedere se si può dare altri dettagli? –

+0

I problemi intermittenti come quello in genere indicano un problema hardware. Se è davvero necessario riavviare la macchina dopo un errore, allora sospetto molto fortemente l'hardware. Cosa succede se provi a copiare il file usando COPY o ROBOCOPY o XCOPY? –

+0

@NicoleDesRosiers Sembra uno strumento utile. Grazie per la raccomandazione Jim: tutti questi metodi richiedono le stringhe del percorso file. Non riesco a trovare un modo per creare un file per un'unità non formattata che restituisce una stringa. –

risposta

1

Ho avuto problemi simili leggendo da scanner. Ho finito per dover rilevare l'eccezione, attendere un po 'di tempo (250 ms hanno funzionato bene per i miei scopi), quindi provare a rileggere di nuovo gli stessi dati. Ho definito una soglia (6 ha funzionato bene per me) a quel punto ho rinunciato e ha sollevato un errore per l'utente.

Questo sembrava dare l'hardware abbastanza tempo per recuperare la maggior parte dei casi.

Inoltre, prova a leggere solo il blocco che ti dà problemi. Se ricevi costantemente un errore nella lettura di un blocco specifico, allora hai ovviamente un problema hardware.

Problemi correlati