locked
Why can't I upload a large file even when using "chunking" with http handler? RRS feed

  • Question

  • I have some code I've been using for a while to upload files. The code was modeled after some code I found on the web. It makes multiple requests which each include a "chunk" of the file. Then the file "appends" the new chunk to the file.

    This all seemed to work for files larger than the chunk size, but now I've had failures.  It goes along swimmingly and then suddenly gets a "file in use" error saying some other process is using the file.  My process is the only thing that *I* know would be using it. Is maybe Microsoft doing something when I am sending another chunk?  Like maybe scanning it for viruses or something? 

    Or, is there some resource that isn't being freed quickly enough in .net?

    Here is my code on the server (in RemObject's Oxygene language):

       procedure FileUploadProcess.ProcessAttachment( context : HttpContext; surveyNumber : String; filename : String; fullFilename : String  );
          var 
             complete  : Boolean;
             startByte : Int64;
             fi        : FileInfo;
             args      : FileUploadCompletedEventArgs;
          begin
          complete       := iif( String.IsNullOrEmpty( context.Request.QueryString[ 'Complete'     ] ), true,         Boolean.Parse(  context.Request.QueryString[
     'Complete'     ] ) );
          startByte      := iif( String.IsNullOrEmpty( context.Request.QueryString[ 'StartByte'    ] ), 0,            Int64.Parse(   
     context.Request.QueryString[ 'StartByte'    ] ) );
    
          fi       := new FileInfo( fullFilename );
          
          try
             if (startByte > 0) and 
                fi.Exists then begin
                using fs := File.OpenWrite( fullFilename ) do begin
                   fs.Position := startByte;
                   SaveFile( context.Request.InputStream, fs );
                   end;
                end
             else begin
                File.Delete( fullFilename ); // will replace the TEMP file that is uploaded
                using fs := File.Create( fullFilename ) do begin
                   SaveFile( context.Request.InputStream, fs );
                   end;
                end;
    
          except
             on E: WebException do begin
                context.Response.ContentType := 'text/plain';
    
                context.Response.Write( 'Error saving file to: ' + filename + Environment.NewLine + E.Message );
                context.Response.Flush;
                end;
             on E: Exception do begin
                context.Response.ContentType := 'text/plain';
    
                context.Response.Write( 'Error saving file to: ' + filename + Environment.NewLine + E.Message );
                context.Response.Flush;
                end;
             end;
          if complete then begin
             context.Response.Flush;
             if FileUploadCompleted <> nil then begin
                args := new FileUploadCompletedEventArgs( surveyNumber, filename );
                FileUploadCompleted( self, args )
                end;
             end;
          end;
       procedure FileUploadProcess.SaveFile( inputStream : Stream; outputFS : FileStream );
          var 
             buffer    : array of Byte;
             bytesRead : Int32;
          function MoreBytesToWrite : Boolean;
             begin
             bytesRead := inputStream.Read( buffer, 0, buffer.Length );
             result    := bytesRead <> 0;
             end;
          begin
          try
             buffer := new array[400000] of Byte;
          
             while MoreBytesToWrite do begin
                outputFS.Write( buffer, 0, bytesRead );
                end;
             buffer := nil;
          finally
             outputFS.Flush;
             outputFS.Close;  // using is supposed to take care of this
             end;
          end;



    • Edited by Mark Tiede Tuesday, January 19, 2016 7:09 PM
    Tuesday, January 19, 2016 7:08 PM

Answers

  • I THINK what is happening is antivirus or Defender in Win10 is wanting to lock the file while scanning it. And then my code can't open or delete it. I added delay exception loops around those critical pieces that will retry for a reasonable number of times before raising the exception again.

    I also flushed, closed, and disposed of the INPUTSTREAM.  I was afraid that it would mess something up because *I* didn't create the stream, but thing seem more stable now that I do that.

    • Marked as answer by Mark Tiede Wednesday, January 20, 2016 7:33 PM
    Wednesday, January 20, 2016 7:33 PM