c# - Hash a file as its being recived -


end goal: users uploading large number of files in different sizes web site. , dont want duplicate files on disk.

the solution have been using simple sh1 hash of file when uploaded. code this:

public static string hashfile(string filename) {    using (filestream stream = file.openread(filename))    {       sha1managed sha = new sha1managed();       byte[] checksum = sha.computehash(stream);        string sendchecksum = bitconverter.tostring(checksum).replace("-",string.empty);                     return sendchecksum;    }  } 

this "works" fine smaller files, big pain when file 30gb. hash file im reciving client. file client in "chunks" , size of chunk not static.

code recives file.

int chunk = context.request["chunk"] != null ? int.parse(context.request["chunk"]) : 0; int chunks = context.request["chunks"] != null ? int.parse(context.request["chunks"]) : 0; string filename = context.request["name"] != null ? context.request["name"] : string.empty;  httppostedfile fileupload = context.request.files[0];     string fullfilepath = path.combine(sitesettings.uploadtempfolder, filename); using (var fs = new filestream(fullfilepath, chunk == 0 ? filemode.create : filemode.append)) {     var buffer = new byte[fileupload.inputstream.length];     fileupload.inputstream.read(buffer, 0, buffer.length);      fs.write(buffer, 0, buffer.length);     **// here want hash, when have file data in memory.** } 

you can create own stream :)

public class actionstream : stream {     private readonly stream _innerstream;     private readonly action<byte[], int, int> _readaction;      public actionstream(stream innerstream, action<byte[], int, int> readaction)     {         _innerstream = innerstream;         _readaction = readaction;     }      public override bool canread => true;     public override bool canseek => false;     public override bool canwrite => false;     public override long length => _innerstream.length;     public override long position     {         { return _innerstream.position; }         set { throw new notsupportedexception(); }     }      public override void flush() { }      public override int read(byte[] buffer, int offset, int count)     {         var bytesread = _innerstream.read(buffer, offset, count);          _readaction(buffer, offset, bytesread);          return bytesread;     }      public override long seek(long offset, seekorigin origin)     {         throw new notsupportedexception();     }      protected override void dispose(bool disposing)     {         if (disposing)         {             _innerstream.dispose();         }          base.dispose(disposing);     }      public override void setlength(long value) { throw new notsupportedexception(); }      public override void write(byte[] buffer, int offset, int count)      {        throw new notsupportedexception();      } } 

this allows bind 2 stream operations you're doing:

using (var fs = new filestream(path, chunk == 0 ? filemode.create : filemode.append)) {   var = new actionstream(fileupload.inputstream,     (buffer, offset, bytesread) =>     {       fs.write(buffer, offset, bytesread);     });    var sha = new sha1managed();   var checksum = sha.computehash(as); } 

this assumes sha1manager reads through every single byte of input stream in order - should check that. i'm pretty sure how works, though :)


Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -