Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FileStream.WriteFile的奇怪行为_C#_File Io_Filestream - Fatal编程技术网

C# FileStream.WriteFile的奇怪行为

C# FileStream.WriteFile的奇怪行为,c#,file-io,filestream,C#,File Io,Filestream,我正在开发一个程序,可以对大文件(直到64GB)进行大量的读/写随机访问。文件是专门结构化的,为了访问它们,我创建了一个框架;过了一段时间,我尝试测试它的性能,我注意到在预分配的文件上,顺序写入操作太慢,无法接受。 在多次测试之后,我在没有框架的情况下复制了该行为(只有FileStream方法);以下是(使用我的硬件)复制问题的代码部分: FileStream fs = new FileStream("test1.vhd", FileMode.Open); byte[] buffer = new

我正在开发一个程序,可以对大文件(直到64GB)进行大量的读/写随机访问。文件是专门结构化的,为了访问它们,我创建了一个框架;过了一段时间,我尝试测试它的性能,我注意到在预分配的文件上,顺序写入操作太慢,无法接受。 在多次测试之后,我在没有框架的情况下复制了该行为(只有FileStream方法);以下是(使用我的硬件)复制问题的代码部分:

FileStream fs = new FileStream("test1.vhd", FileMode.Open);
byte[] buffer = new byte[256 * 1024];
Random rand = new Random();
rand.NextBytes(buffer);
DateTime start, end;
double ellapsed = 0.0;
long startPos, endPos;

BinaryReader br = new BinaryReader(fs);
br.ReadUInt32();
br.ReadUInt32();
for (int i = 0; i < 65536; i++)
    br.ReadUInt16();

br = null;

startPos = 0;   // 0
endPos = 4294967296;    // 4GB
for (long index = startPos; index < endPos; index += buffer.Length)
{
    start = DateTime.Now;
    fs.Write(buffer, 0, buffer.Length);
    end = DateTime.Now;
    ellapsed += (end - start).TotalMilliseconds;
}
FileStream fs=newfilestream(“test1.vhd”,FileMode.Open);
字节[]缓冲区=新字节[256*1024];
Random rand=新的Random();
下一字节随机数(缓冲区);
日期时间开始,结束;
双ellapsed=0.0;
长startPos,endPos;
BinaryReader br=新的BinaryReader(fs);
br.ReadUInt32();
br.ReadUInt32();
对于(int i=0;i<65536;i++)
br.ReadUInt16();
br=null;
startPos=0;//0
endPos=4294967296;//4GB
for(长索引=startPos;索引
不幸的是,这个问题似乎是不可预测的,所以有时它“起作用”,有时它不起作用。 但是,使用Process Monitor,我捕获了以下事件:

Operation Result Detail WriteFile SUCCESS Offset: 1.905.655.816, Length: 262.144 WriteFile SUCCESS Offset: 1.905.917.960, Length: 262.144 WriteFile SUCCESS Offset: 1.906.180.104, Length: 262.144 WriteFile SUCCESS Offset: 1.906.442.248, Length: 262.144 WriteFile SUCCESS Offset: 1.906.704.392, Length: 262.144 WriteFile SUCCESS Offset: 1.906.966.536, Length: 262.144 ReadFile SUCCESS Offset: 1.907.228.672, Length: 32.768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal WriteFile SUCCESS Offset: 1.907.228.680, Length: 262.144 ReadFile SUCCESS Offset: 1.907.355.648, Length: 32.768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal ReadFile SUCCESS Offset: 1.907.490.816, Length: 32.768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal WriteFile SUCCESS Offset: 1.907.490.824, Length: 262.144 ReadFile SUCCESS Offset: 1.907.617.792, Length: 32.768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal ReadFile SUCCESS Offset: 1.907.752.960, Length: 32.768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal WriteFile SUCCESS Offset: 1.907.752.968, Length: 262.144 操作结果详细信息 写入文件成功偏移量:1.905.655.816,长度:262.144 写入文件成功偏移量:1.905.917.960,长度:262.144 写入文件成功偏移量:1.906.180.104,长度:262.144 写入文件成功偏移量:1.906.442.248,长度:262.144 写入文件成功偏移量:1.906.704.392,长度:262.144 写入文件成功偏移量:1.906.966.536,长度:262.144 ReadFile成功偏移量:1.907.228.672,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常 写入文件成功偏移量:1.907.228.680,长度:262.144 ReadFile成功偏移量:1.907.355.648,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常 ReadFile成功偏移量:1.907.490.816,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常 写入文件成功偏移量:1.907.490.824,长度:262.144 ReadFile成功偏移量:1.907.617.792,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常 ReadFile成功偏移量:1.907.752.960,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常 写入文件成功偏移量:1.907.752.968,长度:262.144 也就是说,在过度写入近2GB之后,
FileStream.Write
在每次
WriteFile
之后开始调用
ReadFile
,并且这个问题一直持续到流程结束;此外,问题开始的偏移量似乎是随机的。 我已经在
FileStream.Write
方法中一步一步地进行了调试,并且我已经验证了实际上是
WriteFile
(Win32 API),它在内部调用
ReadFile


最后一点;我不认为这是一个文件碎片的问题:我已经整理了文件与康蒂格个人

我认为这与FileStream.Write/Read和2GB限制有关。您是否在32位进程中运行此操作?我找不到关于这方面的任何具体文档,但这里有一个听起来相同的问题。您可以尝试在64位进程中运行它


不过,我同意使用内存映射文件可能是一种更好的方法。

我从MSDN中找到了这一点。有关系吗?听起来每个文件都有一个全局共享指针

当FileStream对象的句柄上没有独占保持时,另一个线程可以同时访问该文件句柄,并更改与该文件句柄关联的操作系统文件指针的位置。在这种情况下,FileStream对象中的缓存位置和缓冲区中的缓存数据可能会受到影响。FileStream对象定期检查访问缓存缓冲区的方法,以确保操作系统的句柄位置与FileStream对象使用的缓存位置相同


考虑切换内存。您的意思是我应该从Win32 API创建引用还是使用.NET4?在第一种情况下,最好用C/C++创建整个框架(我真的在考虑这种可能性!);在后者中,我还应该升级到VS2010或使用SharpDevelop:我更喜欢使用我拥有的!这可能是操作系统缓冲问题,我无法在Win7 x64和.Net 4.0上复制读取。(另外,请使用
使用
块,我今天不想哭)我已经添加了FileOptions.WriteThrough to constructor:no changes!文件系统缓存的RAM不足。由于您现在只能以磁盘的写入速度进行写入,因此写入速度会急剧下降。获取更多内存。我在Win7 64位系统中!但是我不认为这是FileStream的问题!那是很有可能的。据我所知,.NET仍然限于32位进程或2GB内存限制。但是您分配的文件没有超过2GB,所以我怀疑这是问题所在。net应用程序是否以“任何CPU”或x86为目标?.net的FileStream.Write/Read可以处理大于2GB的文件。@SixlettVariables:是的,您是对的:它可以!如果没有,如何创建4 GB文件???根据文档,似乎足以使用
FileOptions。WriteThrough
禁用
FileStream之间的每个缓存。Write
和磁盘;但是在测试期间,我仍然观察到
ReadFile
的存在。