Bassman2 / MediaDevices

MTP Library
MIT License
98 stars 36 forks source link

OutOfMemoryException when downloading large files #101

Open sun2sirius opened 1 year ago

sun2sirius commented 1 year ago

Describe the bug Downloading a ~2GB video file throws System.OutOfMemoryException while in the DownloadFile(path, stream) method.

To Reproduce Call the DownloadFile(path, stream) method with a valid path and a newly created stream. Smaller files ~1GB and below download fine, but starting from some size, like 1.x GB, an OutOfMemoryException is triggered.

Expected behavior The DownloadFile(path, stream) method should handle files of any size, including large videos of several GB.

Device Windows 10 on Lenovo P53. Same behavior is also observed on other devices (Dell and Lenovo) and Windows 11.

Version: 1.9.1

Additional context

NilsHoyer commented 1 month ago

If I'm right, it's a problem of the used StreamWrapper class.

And I wish some support / updates too. But if Ralf don't offer this... Nevertheless, for smaller files, this project is great for me.

sun2sirius commented 1 month ago

I use it for a program I wrote to backup/sync photos/videos from iPhones. Now that videos are 4K HDR 60 fps, they often get pretty large. For the files over 1GB I invoke Beyond Compare like this:

        if (devFile.Length / 1024 / 1024 > 1000)
        {
            string scriptFile = Path.GetTempFileName();
            string logFile = Path.GetTempFileName();
            string script = "log normal \"" + logFile + "\"\r\n" +
                "load " + "\"mtp://Apple iPhone" + iPhonePath + devFile.Directory.Name + "\" \"" + localDir.FullName + "\"\r\n" +
                "filter \"" + devFile.Name + "\"\r\n" +
                "sync mirror:left->right\r\n";

            File.WriteAllText(scriptFile, script);

            Process p = new Process();
            p.StartInfo.FileName = "BCompare.exe";
            p.StartInfo.Arguments = "@" + scriptFile;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start();
            p.WaitForExit();

            File.Delete(scriptFile);
            File.Delete(logFile);
            return;
        }