它能够做到这一点,但会随机抛出文件未找到异常。例如,它会读取一两个GB,然后抛出异常。其他时候,它会连续几次读取所有8 GB,然后抛出异常。换句话说,它似乎完全是随机弹出的。
我不知道可能是什么原因导致的。
编辑:我已经使用反馈来微调一些东西。下面粘贴的是更新后的代码。
它仍然会随机抛出文件未找到异常,但现在在尝试读取第8 GB的第432 MB时始终会抛出参数异常(如果没有随机抛出文件未找到异常)。
错误提示文件句柄不支持同步操作。
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[] buffer, int32 offset, int32 count) 中
在 System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count) 中
在 System.IO.BinaryReader.Read(Byte[] buffer, Int32 index, Int32 count) 中
在 RawSDAccessTest.Program.Main(String{} args) 中的 C:\Users\etc... 的第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: SUCCESS Offset: 3,228,565,504, Length: 1,048,576, I/O Flags: Non-cached, Priority: Normal
8:40:26.1745974 AM SDCardReadAttempt3.vshost.exe 2432 ReadFile E: NO SUCH DEVICE Offset: 3,229,614,080, Length: 131,072, I/O Flags: Non-cached, Priority: Normal
因此,在读取期间,设备停止存在。我将文件的创建和删除移动到内部循环中,以便每次尝试从中读取时都会创建该文件。问题仍然存在。这让我想到可能是硬件引起的。
编辑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 Flags: Non-cached, Priority: Normal
我不知道 .net 是如何深入工作的。也许它将其转换为多线程过程,而该文件没有打开,以供多个线程读取。我将等待时间加回去来看是否可以消除这个错误,以便我可以回到原始错误进行修复。