Handling with temporary file stream

前端 未结 5 977
南方客
南方客 2021-01-02 22:47

Say I want to define a TempFileStream class that creates a temporary file using Path.GetTempFileName() method. A temporary file must be deleted when TempFileStream\'s object

5条回答
  •  梦谈多话
    2021-01-02 23:23

    I know this is an older thread, but here's an alternate solution. I started to implement the TempFileStream, but I wanted more concurrency. My use-case involves exporting [potentially MBs of] database results to a CSV file via MVC. I want to begin downloading to the client as soon as data are available from the database query rather than wait for a potentially large temp file to be written before I start downloading.

    In this solution, I launch the query in a separate thread which fills an AnonymousPipeStream. The main thread can then slurp the data from the other end of the pipe as its available. It uses .Net 4 Tasks.

    Hope someone else finds this useful.

    -Rob

    Controller method:

    public FileResult ResultExport ( ReportOptions options )
    {
        ResultExport rpt = new ResultExport( options );
        HttpContext.Response.BufferOutput = false;
        return File( rpt.Export(), "text/csv", "results.csv" );
    }
    

    Model:

    public ResultExport
    {
        private AnonymousPipeServerStream WriteStream = null;
    
        public Stream Export()
        {
            //
            // We'll fire off the database query in a background
            // thread.  It will write data to one end of the pipe.  We'll return the reader
            // end of that pipe to our caller.
            //
            WriteStream = new AnonymousPipeServerStream( PipeDirection.Out );
            AnonymousPipeClientStream reader = new AnonymousPipeClientStream( PipeDirection.In, WriteStream.ClientSafePipeHandle );
    
            //
            // Call Execute() in a background thread.
            //
            Task.Factory.StartNew( () => Execute() );
    
            //
            // While Execute() is filling the pipe with data,
            // return the reader end of the pipe to our caller.
            //
            return reader;
        }
    
        private void Execute ()
        {
            //
            // WriteStream should only by populated by Export()
            //
            if( WriteStream != null )
            {
                using ( StreamWriter sw = new StreamWriter( WriteStream, Encoding.UTF8, 4096 ) )
                {
                    //
                    // Shove data into the StreamWriter as we get it from the database
                    //
                    foreach ( string line in ExportCore() )
                    {
                        // Each line is a comma-delimited set of values
                        sw.WriteLine( line );
                    }
                }
            }
        }
    }
    

提交回复
热议问题