フォーマットされていない SD カードから 8 GB の 16 進データを読み取る C# ツールを開発しています。
これは可能ですが、ランダムに File Not Found Exception をスローします。たとえば、1 ~ 2 ギガバイトを読み取ってからスローします。それ以外の場合は、8 GB すべてを数回続けて読み取り、例外をスローします。つまり、完全にランダムにポップアップするように見えます。
何が原因なのかわかりません。
編集: フィードバックを使用して、いくつかのことを微調整しました。以下に貼り付けられているのは、更新されたコードです。
それでもランダムに filenotfound 例外がスローされますが、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) at System.IO.FileStream.ReadCore(Byte[] buffer, int32 offset, int32 count) at System.IO.FileStream.Read( C:\Users\etc の RawSDAccessTest.Program.Main(String{} args) の System.IO.BinaryReader.Read(Byte[] バッファー、Int32 インデックス、Int32 カウント) の Byte[] 配列、Int32 オフセット、Int32 カウント) ... 67 行目ターゲット サイト: Void 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: 成功オフセット: 3,228,565,504、長さ: 1,048,576、I/O フラグ: 非キャッシュ、優先度: 通常
8:40:26.1745974 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: そのようなデバイスはありません オフセット: 3,229,614,080、長さ: 131,072、I/O フラグ: 非キャッシュ、優先度: 通常
したがって、読み取りの合間に、デバイスは存在しなくなります。ファイルの作成と削除を内側のループに移動して、ファイルから読み取ろうとするたびにファイルを作成するようにしました。問題は解決しません。ハードウェアの匂いがします。
編集 2: 非同期読み取り例外がスローされることがあります。
9:16:16.1129926 AM SDCardReadAttempt3.vshost.exe 3752 ReadFile E: INVALID PARAMETER オフセット: 7,969,177,600、長さ: 1,048,576、I/O フラグ: 非キャッシュ、優先度: 通常
.net が奥深くでどのように機能するかはわかりません。ファイルが複数のスレッドで読み取られるように開かれていない場合、これをスレッド化されたプロセスにしている可能性があります。元のエラーに戻ることができるように、このエラーが解消されるかどうかを確認するために、待機をそこに戻します。