c# - How to create fast and efficient filestream writes on large sparse files -


i have application writes large files in multiple segments. use filestream.seek position each wirte. appears when call filestream.write @ deep position in sparse file write triggers "backfill" operation (writeing 0s) on preceding bytes slow.

is there more efficient way of handling situation?

the below code demonstrates problem. initial write takes 370 ms on machine.

    public void writetostream()     {         datetime dt;         using (filestream fs = file.create("c:\\testfile.file"))         {                fs.setlength(1024 * 1024 * 100);             fs.seek(-1, seekorigin.end);             dt = datetime.now;             fs.writebyte(255);                       }          console.writeline(@"write ms: " + datetime.now.subtract(dt).totalmilliseconds.tostring());     } 

ntfs support sparse files, there no way in .net without p/invoking native methods.

it not hard mark file sparse, know once file marked sparse file can never converted in non sparse file except coping entire file in new non sparse file.

example useage

class program {     [dllimport("kernel32.dll", setlasterror = true, charset = charset.auto)]     private static extern bool deviceiocontrol(         safefilehandle hdevice,         int dwiocontrolcode,         intptr inbuffer,         int ninbuffersize,         intptr outbuffer,         int noutbuffersize,         ref int pbytesreturned,         [in] ref nativeoverlapped lpoverlapped     );      static void markassparsefile(safefilehandle filehandle)     {         int bytesreturned = 0;         nativeoverlapped lpoverlapped = new nativeoverlapped();         bool result =             deviceiocontrol(                 filehandle,                 590020, //fsctl_set_sparse,                 intptr.zero,                 0,                 intptr.zero,                 0,                 ref bytesreturned,                 ref lpoverlapped);         if(result == false)             throw new win32exception();     }      static void main()     {         //use stopwatch when benchmarking, not datetime         stopwatch stopwatch = new stopwatch();          stopwatch.start();         using (filestream fs = file.create(@"e:\test\test.dat"))         {             markassparsefile(fs.safefilehandle);              fs.setlength(1024 * 1024 * 100);             fs.seek(-1, seekorigin.end);             fs.writebyte(255);         }         stopwatch.stop();          //returns 2 sparse files , 1127 non sparse         console.writeline(@"write ms: " + stopwatch.elapsedmilliseconds);      } } 

once file has been marked sparse behaves excepted behave in comments too. don't need write byte mark file set size.

static void main() {     string filename = @"e:\test\test.dat";      using (filestream fs = new filestream(filename, filemode.create))     {         markassparsefile(fs.safefilehandle);          fs.setlength(1024 * 1024 * 25);     } } 

enter image description here


Comments

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -