Solved

Buffer 40MB or larger files does not work

Posted on 2012-03-19
3
297 Views
Last Modified: 2012-03-21
Hi

I have this code: what it does is it loads a mp3 file into memory, (using jwplayer), with small files (under 7mb) I can skip forward or move back. But when I load a 40mb file it look like it has to load the whole file into memory. So I cant move forward or back (user exp sucks).

Does anyone know how to get this to work?


public static void ResumableFile(string filename, string fullpath, string contentType)
    {
        System.IO.Stream iStream = null;

        // Buffer to read 10K bytes in chunk:
        byte[] buffer = new Byte[10000];

        int length;
        
        try
        {
            FileStream myFile = new FileStream(fullpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            BinaryReader br = new BinaryReader(myFile);
            try
            {
                iStream = new System.IO.FileStream(fullpath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);          
                
                HttpContext.Current.Response.AddHeader("Accept-Ranges", "bytes");
                HttpContext.Current.Response.Buffer = false;

                // Total bytes to read:
                long fileLength = myFile.Length;
                
                long startBytes = 0;

                //int pack = 10240; //10K bytes


                int pack = 1048576; //1024K bytes

                if (HttpContext.Current.Request.Headers["Range"] != null)
                {
                    HttpContext.Current.Response.StatusCode = 206;
                    string[] range = HttpContext.Current.Request.Headers["Range"].Split(new char[] { '=', '-' });
                    startBytes = Convert.ToInt64(range[1]);
                }
                HttpContext.Current.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                if (startBytes != 0)
                {
                    HttpContext.Current.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                }
                HttpContext.Current.Response.AddHeader("Connection", "Keep-Alive");
                HttpContext.Current.Response.ContentType = contentType;
                //HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8));

                br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;

                // Read the bytes.
                while (fileLength > 0)
                {
                    // Verify that the client is connected.
                    if (HttpContext.Current.Response.IsClientConnected)
                    {
                        // Read the data in buffer.
                        length = iStream.Read(buffer, 0, 10000);

                        // Write the data to the current output stream.
                        HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);

                        // Flush the data to the HTML output.
                        HttpContext.Current.Response.Flush();

                        buffer = new Byte[10000];
                        fileLength = fileLength - length;
                    }
                    else
                    {
                        //prevent infinite loop if user disconnects
                        fileLength = -1;
                    }
                }
            }
            catch
            {
                HttpContext.Current.Response.ContentType = "text/html";
                HttpContext.Current.Response.Write("Error : file not found");
            }
            finally
            {
                br.Close();
                myFile.Close();
            }
        }
        catch
        {
            HttpContext.Current.Response.ContentType = "text/html";
            HttpContext.Current.Response.Write("Error : file not found");
        }
    }

Open in new window

0
Comment
Question by:mousemat24
  • 2
3 Comments
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 500 total points
ID: 37737339
>>But when I load a 40mb file it look like it has to load the whole file into memory.

Correct - that is what you have coded (read the file in the while loop).

>>Does anyone know how to get this to work?

Yes - don't use the while loop, read the first buffer load then read only when it is required.  (Maybe you should read the file in a thread)
0
 

Author Comment

by:mousemat24
ID: 37737366
AndyAinscow, dont suppose you can send me the code? Many thanks
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 37737582
It is basically what you currently have - just remove the while loop and keep track of how much you have read from the file.
0

Featured Post

Guide to Performance: Optimization & Monitoring

Nowadays, monitoring is a mixture of tools, systems, and codes—making it a very complex process. And with this complexity, comes variables for failure. Get DZone’s new Guide to Performance to learn how to proactively find these variables and solve them before a disruption occurs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
asp web application 3 43
ASP.net Will we ever be able to build mobile apps in it 6 32
Need help with a query 14 39
Display info from DB to Label in asp.net 7 16
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question