Estoy tratando de determinar la peor velocidad de disco de caso, así que escribí la siguiente función.Cómo hacer grabaciones de archivos no en caché en la aplicación winform C#
static public decimal MBytesPerSec(string volume)
{
string filename = volume + "\\writetest.tmp";
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename);
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
char[] data = new char[64000];
Stopwatch watch = new Stopwatch();
watch.Start();
int i = 0;
for (; i < 1000; i++)
{
file.Write(data);
if (watch.ElapsedMilliseconds > 2000)
{
break;
}
}
watch.Stop();
file.Close();
System.IO.File.Delete(volume + "\\test.txt");
decimal mbytessec = (i * 64/watch.ElapsedMilliseconds);
return mbytessec;
}
La función funciona bien, pero las escrituras están consiguiendo almacena en caché, por lo que la velocidad no es peor de los casos.
En WIN32 C++, yo simplemente crear el archivo con FILE_FLAG_NO_BUFFERING
, FILE_FLAG_WRITE_THROUGH
opciones y, a continuación, asegúrese de seguir las reglas sin almacenamiento en caché de escritura (escribir en el fichero en desplazamientos tamaño del sector, con un mínimo de 4k escribe)
Encontré un article que analiza la técnica .NET.
Así que escribí una nueva función (ignore los errores matemáticos).
static public decimal MBytesPerSecNonCached(string volume)
{
const FileOptions FILE_FLAG_NO_BUFFERING = (FileOptions)0x20000000;
string filename = volume + "\\writetest.tmp";
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1024, FileOptions.WriteThrough | FILE_FLAG_NO_BUFFERING))
{
byte[] data = new byte[65535];
int i = 0;
Stopwatch watch = new Stopwatch();
watch.Start();
for (; i < 1000; i++)
{
fs.Write(data, 0, 65535);
if (watch.ElapsedMilliseconds > 2000)
{
break;
}
}
watch.Stop();
fs.Close();
System.IO.File.Delete(filename);
decimal mbytessec = (i * 64/watch.ElapsedMilliseconds);
return mbytessec;
}
}
Esta función se puede utilizar para 4k, 16K y 32K escriben tamaños, pero una vez que lo intento 64K escribir tamaños, me sale una excepción:
IO operation will not work. Most likely the file will become too long or the handle was not opened to support synchronous IO operations.
Entonces, ¿cómo puedo solucionar este problema para que pueda probar con tamaños de escritura mayores a 32KB (64KB a 4096KB)?
.NET Framework fue desarrollado para eliminar esas decisiones del desarrollador y permitir que el marco lo administre "para usted". La buena noticia es que, para el 99% de las necesidades, es bastante bueno en eso. La mala noticia es que no quiere darte ese control cuando sientes que lo necesitas (o simplemente lo QUIERES). La solución, si está interesado en hacerlo, "usted mismo" es usar PInvoke para direccionar las DLL de Win32 y luego hacerlo de la misma manera que lo haría en C++. –