2013-06-04 56 views
9

我正在開發一個C#工具,用於從未格式化的SD卡中讀取8 gb的十六進制數據。FileNotFoundException隨機引發

它能夠這樣做,但它隨機拋出未找到文件異常。例如,它會讀取一個或兩個字節,然後丟棄它。其他時候,它會連續幾次讀取全部8克,然後拋出異常。換句話說,它似乎完全隨機彈出。

我不知道是什麼原因造成的。

編輯:我用反饋來調整一些東西。下面粘貼的是更新後的代碼。

它仍然隨機拋出filenotfoundexception,但它現在總是拋出一個參數異常,當它試圖讀取演出8的MB 432(如果它得到那麼遠,沒有隨機拋出filenotfound)。

錯誤提示文件句柄不支持同步操作。

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

下面我重新寫了顯示用於FileNotFoundException異常錯誤:

消息:無法找到指定的文件。 來源:mscorlib程序 堆棧跟蹤:在System.IO .__ Error.WinIOError(INT32錯誤代碼,字符串maybeFullPath) 在System.IO.FileStream.ReadCore(字節[]緩衝液,INT32偏移,INT32計數) 在System.IO.FileStream.Read(Byte [] array,Int32 offset,Int32 count) at System.IO.BinaryReader.Read(Byte [] buffer,Int32 index,Int32 count) at RawSDAccessTest.Program.Main(字符串{} args)在C:\ Users \ etc ...在第67行 目標站點:無效WinIOError(Int32,System.String) System.IO.FileNotFoundException:無法找到指定的文件。 第67行是: reader.Read(buffer,0,1048576);

我在這裏發現真奇怪的是,程序對65行來說非常合適,它也使用讀者對象。不知怎的,在執行第65和67行之間,它決定該文件不再存在。我把等待放在兩者之間,看看是否能解決問題。它沒有。

任何想法可能會導致它隨機拋出這個異常,或如何解決它?

編輯:進程監視器顯示以下

8:40:26.1077157 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile的E:SUCCESS偏移:3228565504,長度:1048576,I/O標誌:非緩存,優先級:普通

8:40:26.1745974 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile的E:沒有這樣的設備偏移:3229614080,長度:131,072,I/O標誌:非緩存,優先級:普通

所以在兩者之間讀取,設備不復存在。我將文件的創建和刪除移動到了內部循環中,以便每次嘗試讀取文件時都會創建該文件。問題依然存在。聞起來像硬件給我。

編輯2:現在它偶爾會拋出異步讀取異常。

9:16:16.1129926 AM SDCardReadAttempt3.vshost.exe 3752 ReadFile的E:無效的參數偏移:7969177600,長度:1,048,576,I/O標誌:非緩存,優先級:普通

我不知道.net如何深入瞭解。也許它正在將這個過程變成一個線程化的過程,當這個文件沒有被打開時被多個線程讀取。我會在那裏等待,看看是否消除了這個錯誤,以便我可以回到原來的那個。

+3

你有沒有試過給過程監視器(http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx)一個鏡頭,看看它是否可以給你任何更多的細節? –

+0

像這樣的間歇性問題通常表示硬件問題。如果確實需要在發生故障後重新啓動機器,那麼我非常強烈地懷疑硬件。如果您嘗試使用COPY或ROBOCOPY或XCOPY複製文件,會發生什麼情況? –

+0

@NicoleDesRosiers看起來像一個有用的工具。感謝您的建議。 Jim:所有這些方法都需要文件路徑字符串。我無法找到一種方法來爲返回字符串的未格式化驅動器創建文件。 –

回答

1

我從掃描儀讀取過類似的問題。我最終不得不趕上這個異常,等待一段時間(250 ms對我的目的很有效),然後再次嘗試重新讀取相同的數據。我定義了一個門檻(6對我來說效果不錯),我放棄了這一點,並向用戶提出了一個錯誤。

這似乎給硬件足夠的時間在大多數情況下趕上。

此外,請嘗試閱讀給你麻煩的塊。如果你一直在讀取特定塊的錯誤,那麼你顯然有硬件問題。