2013-06-04 12 views
9

Opracowuję narzędzie języka C# do odczytu 8-bitowych danych szesnastkowych z niesformatowanej karty SD.FileNotFoundException losowo wyrzucony

Jest w stanie to zrobić, ale losowo zgłasza wyjątek File Found Found. Na przykład odczyta gigabajt lub dwa, a następnie wyrzuci je. Innym razem odczyta wszystkie 8 gbs kilka razy z rzędu, a następnie rzuci wyjątek. Innymi słowy, wygląda na to, że pojawia się zupełnie przypadkowo.

Nie mam pojęcia, co może być przyczyną.

EDYCJA: Wykorzystałem informacje zwrotne, aby poprawić kilka rzeczy. To, co jest wklejone poniżej, to zaktualizowany kod.

Ciągle losowo generuje wyjątek, ale teraz ZAWSZE wyrzuca wyjątek argumentu, gdy próbuje odczytać mb 432 z 8 (jeśli zajdzie tak daleko bez losowego rzucenia Filenotfound).

Błąd polega na tym, że uchwyt pliku nie obsługuje operacji synchronicznych.

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(); 
     } 
    } 
} 

Poniżej ponownie napisał błędu, który jest wyświetlany na FileNotFoundException:

wiadomość: Nie można odnaleźć określonego pliku. Źródło: mscorlib stos Ślad: w System.IO .__ Error.WinIOError (int32 ErrorCode ciąg maybeFullPath) w System.IO.FileStream.ReadCore (bajt [] buforze Int32 offset, Int32 count) w System.IO.FileStream.Read (tablica bajtów [], przesunięcie Int32, liczba Int32) w System.IO.BinaryReader.Read (bufor bajtów [], indeks Int32, liczba Int32) na RawSDAccessTest.Program.Main (String {} args) w C: \ Users \ etc ... w linii 67 Miejsce docelowe: Void WinIOError (Int32, System.String) System.IO.FileNotFoundException: Nie można znajdź określony plik. Linia 67 to: czytnik.Read (bufor, 0, 1048576);

To, co uważam za naprawdę dziwne, to fakt, że program jest całkowicie zgodny z linią 65, która również wykorzystuje obiekt czytnika. W jakiś sposób pomiędzy wykonaniem linii 65 i 67, zdecyduje, że plik już nie istnieje. Wrzuciłem czekanie pomiędzy, żeby zobaczyć, czy to rozwiąże. Tak nie było.

Wszelkie sugestie dotyczące tego, co może być przyczyną tego, że losowo rzuca ten wyjątek lub jak go rozwiązać?

EDIT: Process Monitor pokazuje następujący

8: 40: +26,1077157 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: SUKCES Offset: 3228565504, Długość: 1.048.576, I/O Flagi: Non-buforowane, Priorytet: normalna

8: 40: +26,1745974 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: NIE TAKIE URZĄDZENIE offset: 3,229,614,080, długość: 131,072, I/O Flagi: Non-buforowane, Priorytet: normalny

Więc między czyta, urządzenie przestaje istnieć. Przenieśliśmy tworzenie i usuwanie plików do wewnętrznej pętli, aby utworzyć plik za każdym razem, gdy spróbuje go odczytać. Problem nadal występuje. Pachnie jak sprzęt do mnie.

EDYCJA 2: Od czasu do czasu rzuca asynchroniczny wyjątek odczytu.

9: 16: +16,1129926 AM SDCardReadAttempt3.vshost.exe 3752 ReadFile E: Nieprawidłowy parametr Offset: 7969177600, Długość: 1.048.576, I/O Flagi: Non-buforowane, Priorytet: Normalny

nie wiem jak .net działa głęboko. Być może robi to w procesie gwintowania, gdy plik nie jest otwierany do odczytu przez wiele wątków. Wrzucę tam czekanie, żeby zobaczyć, czy to wyeliminuje ten błąd, abym mógł wrócić do pierwotnego.

+3

Czy próbowali dając Process Monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) strzał, aby zobaczyć, czy mogą dać Ci więcej szczegółów? –

+0

Takie przejściowe problemy zazwyczaj wskazują na problem ze sprzętem. Jeśli naprawdę wymaga ponownego uruchomienia komputera po awarii, to bardzo mocno podejrzewam sprzęt. Co stanie się, jeśli spróbujesz skopiować plik za pomocą COPY lub ROBOCOPY lub XCOPY? –

+0

@NicoleDesRosiers Wydaje się przydatne narzędzie. Dzięki za rekomendację. Jim: Wszystkie te metody wymagają ciągów do łańcuchów znaków. Nie mogę znaleźć sposobu na utworzenie pliku dla niesformatowanego dysku, który zwraca ciąg znaków. –

Odpowiedz

1

Miałem podobne problemy z czytaniem ze skanerów. Skończyło się na tym, że musiałem złapać wyjątek, odczekać trochę czasu (250 ms działało dobrze dla moich celów), a następnie spróbować ponownie odczytać te same dane. Zdefiniowałem próg (6 działało dobrze dla mnie), w którym to momencie zrezygnowałem i podniosłem błąd dla użytkownika.
To wydawało się dać sprzętowi wystarczająco dużo czasu na nadrobienie zaległości w większości przypadków.

Spróbuj również przeczytać blok, który sprawia kłopoty. Jeśli ciągle pojawia się błąd podczas czytania konkretnego bloku, to oczywiście masz problem ze sprzętem.