FileNotFoundException随机抛出

时间:2013-06-04 17:35:21

标签: c#

我正在开发一个C#工具,用于从未格式化的SD卡读取8 gb十六进制数据。

它能够这样做,但它会随机抛出File Not Found Exception。例如,它会读取一两千兆字节,然后抛出它。其他时候它会连续几次读取所有8 gbs,然后抛出异常。换句话说,它似乎完全随机弹出。

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

编辑:我使用反馈来调整一些事情。下面粘贴的是更新的代码。

它仍会随机抛出filenotfoundexception,但它现在总是在尝试读取gig 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 errorcode,String maybeFullPath) 在System.IO.FileStream.ReadCore(Byte []缓冲区,int32偏移量,int32计数) 在System.IO.FileStream.Read(Byte []数组,Int32偏移量,Int32计数) 在System.IO.BinaryReader.Read(Byte []缓冲区,Int32索引,Int32计数) 在RawSDAccessTest.Program.Main(String {} 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 Offset:3,228,565,504,Length:1,048,576,I / O标志:非缓存,优先级:正常

8:40:26.1745974 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E:NO SUCH DEVICE Offset:3,229,614,080,Length:131,072,I / O标志:非缓存,优先级:正常

因此,在读取之间,设备不再存在。我将文件创建和删除移动到内部循环,以便每次尝试从中读取时都会创建文件。问题依然存在。闻起来像硬件给我。

编辑2:现在它偶尔会抛出一个异步读取异常。

9:16:16.1129926 AM SDCardReadAttempt3.vshost.exe 3752 ReadFile E:INVALID PARAMETER Offset:7,969,177,600,Length:1,048,576,I / O标志:非缓存,优先级:正常

我不知道.net如何深入工作。当文件未打开以供多个线程读取时,它可能会将其变为线程化进程。我会把等待放回去看看是否能消除这个错误,所以我可以回到原来的错误。

2 个答案:

答案 0 :(得分:1)

我从扫描仪上读到了类似的问题。我最终不得不抓住异常,等待一段时间(250毫秒适合我的目的),然后尝试重新读取相同的数据。我定义了一个阈值(6对我来说效果很好),此时我放弃并向用户提出错误。

在大多数情况下,这似乎给硬件足够的时间来追赶。

另外,请尝试阅读给您带来麻烦的区块。如果您在读取特定块时始终遇到错误,那么您显然遇到了硬件问题。

答案 1 :(得分:0)

这可能是一个很长的镜头,但你尝试过ReadAsync方法吗?
http://msdn.microsoft.com/en-us/library/hh137813.aspx