flutter_file_picker icon indicating copy to clipboard operation
flutter_file_picker copied to clipboard

The problem with big files

Open szbk opened this issue 3 years ago • 38 comments

I want to reach the size of the video files on the device. Low size videos are okay (eg 50mb). But if the file size is too big, it takes too long (eg 4gb). Sometimes it doesn't work. How can I directly access the path of the file I selected? When the file size is large, cache loading is a problem. I am having this problem on android.

szbk avatar Dec 27 '20 12:12 szbk

@sbilketay there isn't much to do here, unfortunately. Files are copy cached in chunks which is great to prevent memory issues, however, 4GB is too much for some devices to handle as you need always 4GB available + some space left.

If you have devices with 10/15 GB of left storage, it shouldn't be an issue (other than just taking the time to download it).

miguelpruivo avatar Dec 27 '20 14:12 miguelpruivo

I'm not interested in downloading files. I want to get the size of a video that is already in the gallery. Is there a way to do this without waiting?

szbk avatar Dec 27 '20 14:12 szbk

@sbilketay right now that isn’t possible. But it’s possible to add as a feature.

miguelpruivo avatar Dec 27 '20 15:12 miguelpruivo

I'm facing this same issue, caching the file then loading for larger files proves to be an issue when reading the files on devices, especially lower performance android devices. Is there a way to append an option to get a direct path?

tmthecoder avatar Mar 05 '21 18:03 tmthecoder

☝️

szbk avatar Mar 05 '21 18:03 szbk

@tmthecoder @sbilketay that's not possible since SDK 30. It is only possible on Android native (through URIs which allows you to manipulate files directly without relying on its original path, however Flutter doesn't support native Android URIs and needs absolute paths for files).

You can read more about it here in the first question.

miguelpruivo avatar Mar 06 '21 20:03 miguelpruivo

Oh, my bad, that's right I forgot about the Scoped Storage stuff on Android. I'm still wondering if there's a way to speed up the process as caching is one of the longest processes in my file work process.

tmthecoder avatar Mar 06 '21 21:03 tmthecoder

I just want to write that I critically need a solution to this issue as well. My app is primarily a video player and some files I want to play are 4GB huge and crashes at file selection.

I can't seem to implement something like resuming video playback because that would require the video to be cached in the app's scoped storage.

My temporary solution is to offer separate versions for users below Android 11 and those on or above it, which is a bit of extra work. With legacy storage, videos play instantly. There isn't copying involved. No videos that have to be moved to cache and clearing after use. No videos that are too huge to play. It just worked.

Scoped storage has been incredibly high maintainance. Secure at the cost of mind numbingly slow limitations. I understand this must be hard to deal with but I would really appreciate any word on a solution to this problem.

lrorpilla avatar Mar 18 '21 15:03 lrorpilla

@lrorpilla unfortunately, the only possible solution for this, is if Dart allows us to create File instances with plataform URIs, at least for Android. There’s no way around since even on native side you don’t use paths to access the file’s contents.

Other way I can think is if we could stream the data directly from each platform, which is doable with some effort I believe but might not fit your use case as well, since you need a File — that’s the bottleneck.

miguelpruivo avatar Mar 20 '21 01:03 miguelpruivo

Following this as we also ran into this issue

isAlmogK avatar Jul 28 '21 14:07 isAlmogK

Maybe we can add some sort of 'withDirect' parameter when opening the file which will stream the data directly from the platform (only applicable to android?). I'd be open to helping write this if needed

tmthecoder avatar Jul 28 '21 22:07 tmthecoder

@lrorpilla unfortunately, the only possible solution for this, is if Dart allows us to create File instances with plataform URIs, at least for Android. There’s no way around since even on native side you don’t use paths to access the file’s contents.

Other way I can think is if we could stream the data directly from each platform, which is doable with some effort I believe but might not fit your use case as well, since you need a File — that’s the bottleneck.

If the APP has MANAGE_EXTERNAL_STORAGE permission, is it possible to use the original path directly?

yullg avatar Aug 06 '21 16:08 yullg

I get memory leakage issue when select a pdf file with size 40mb

tony123S avatar Aug 07 '21 09:08 tony123S

Maybe we can add some sort of 'withDirect' parameter when opening the file which will stream the data directly from the platform (only applicable to android?). I'd be open to helping write this if needed

What would you return to Dart in this case?

miguelpruivo avatar Aug 10 '21 10:08 miguelpruivo

What would you return to Dart in this case?

I was thinking of a callback-style function that we can listen on in dart and add to a Stream with the bytes.

So my thoughts are: Start a BufferedReader in Java --> call Dart callback with the read bytes (of predetermined chunk size) --> add to a Stream<List<int>> that users can listen on

tmthecoder avatar Aug 11 '21 22:08 tmthecoder

@tmthecoder well, that’s sort of the same that happens when you enable withReadStream while picking. Have you already tried?

miguelpruivo avatar Aug 11 '21 23:08 miguelpruivo

@miguelpruivo The withReadStream parameter helps in terms of convenience, but the stream is created from dart, so the file on Android has already been copied over to a locally accessible one, which is what I was aiming to stop. If we use the DocumentFile API to access the file on the Android end (if a specific parameter is set) we can bypass the copying and offer a direct stream of the file's data

tmthecoder avatar Aug 12 '21 04:08 tmthecoder

Is there no way of disabling this caching and moving the responsibility to package users? Picking large files is unbearably slow. package:image_picker for example returns XFiles and explicitly states in the docs that using the path can cause errors and it is recommended to create a local copy. Is there then a similar alternative available in package:file_picker?

This also makes me wonder, how apps such as instagram are able to flawlessly handle huge local files (video) without any noticeable delay for caching.

shilangyu avatar Feb 01 '22 21:02 shilangyu

I have this problem too, I am trying to pick files of an external USB device. The whole point of this is that I don't have enough memory on my device. This caching problem defeats the whole purpose of this! As a workaround, I am currently using getDirectoryPath() instead. This gives me the actual paths of the files and this works perfectly (not counting the hassle, that you can't really select the Videos you want). Then I am wondering why it isn't possible to get the path to the actual file with pickFiles() too.

Proposals: Maybe you could use Symbolic Links to create a link in the cache that points to the actual file! The problem with this may be that FAT file systems (so most SD Cards) don't support them. But since the app cache should be in the internal storage, which, at least what I am aware of, is normally not a FAT file system, this should be no Problem!

Also, you could implement a switch to not cache files and just return an error, if the file exceeds a specified file size. Maybe even dependent on the storage left on the device. This wouldn't really solve the main Problem, but at least, the Application still works if the User tries to cache a file that is too large.

I really hope this can and will be fixed soon!

Dampfwalze avatar Apr 04 '22 14:04 Dampfwalze

Android guidelines don’t allow you to have absolute path access since SDK 30 for files. It’s probably working for you when you use the directory path to access the files, but using the native API to launch the picker and then handling the intent result with the files, don’t allow me to access the absolute paths.

It was possible before, but then refactored due to this limitation. The recommended way to handle the original file is through its URI which is provided in the identifier property but isn’t much useful for a Dart File instance.

I’m not sure if what you’re asking is possible at all at this point, tbh.

miguelpruivo avatar Apr 06 '22 03:04 miguelpruivo

@miguelpruivo Is there any way to restrict the file size while selecting file?

msarkrish avatar Jun 06 '22 12:06 msarkrish

@msarkrish not that I'm aware of (at least, in all platforms). But you can always check the size after the user picks the file and then show an error to the user that the file is too big and discard it.

miguelpruivo avatar Jun 06 '22 13:06 miguelpruivo

@miguelpruivo I can check the file size after user picks the file. The problem with this behavior is If user select the large file(Example: 3GB) then it is not working as expected. So my question is like we pass allowed extension is there any way to pass file size as parameter? If you add this option it will be useful in this scenario.

msarkrish avatar Jun 07 '22 09:06 msarkrish

@msarkrish that's doable however what would happen in that case? Would those files be automatically discarded and the user could think it was a bug? It's hard to implement a clean spec for that use case.

Other option is throwing an error if an user picks a file bigger than X size, that could probably work, although not the best IMO. I'd rather have the pickers to not allow picking files bigger than X size, but it seems that is just a platform limitation.

miguelpruivo avatar Jun 07 '22 11:06 miguelpruivo

@miguelpruivo I can understand. But Do you have any other solution or idea for my problem? MY problem is If i select more than 3GB or big file then it is not sending the selected file and if try to pick another file then it will throw exception as FilePicker is already running. How to fix this issue?

msarkrish avatar Jun 08 '22 17:06 msarkrish

I have the same problem

progid avatar Jul 07 '22 12:07 progid

@szbk @lrorpilla I have tweaked it to prevent unnecessary caching. In Android we cannot get direct paths sometimes especially when file in in downloads folder. This tweaked version doesn't cache every single file. It will retrieve the paths directly most of the time. Files will be cached only if path cannot be retrieved directly. You can try it by using this repo link in pubspec.yaml file. Tweaked file-picker

abhi16180 avatar Sep 19 '22 06:09 abhi16180

Thanks @abhi16180, I'll try to look into your fork sometime.

Just as an update because I still subscribe to this issue, I use filesystem_picker and supply root paths from external_path as an initial path and just list all the files in a directory and display them all in Flutter UI.

Really my use case just requires the absolute file path to be able to make a file for a video player, so I just use a non-native file picker made with Flutter that lists everything in a directory and allows navigating and changing directories. Really being able to list every file in a directory allows me to have the absolute path I need.

It's unfortunate I couldn't do this with the native picker plugins like this one, but to people who have a similar use case, you could consider what I did, it also allows you to have control over your UI.

lrorpilla avatar Sep 19 '22 06:09 lrorpilla

Thanks @abhi16180, I'll try to look into your fork sometime.

Just as an update because I still subscribe to this issue, I use filesystem_picker and supply root paths from external_path as an initial path and just list all the files in a directory and display them all in Flutter UI.

Really my use case just requires the absolute file path to be able to make a file for a video player, so I just use a non-native file picker made with Flutter that lists everything in a directory and allows navigating and changing directories. Really being able to list every file in a directory allows me to have the absolute path I need.

It's unfortunate I couldn't do this with the native picker plugins like this one, but to people who have a similar use case, you could consider what I did, it also allows you to have control over your UI.

Yeah I will look into filesystem_picker package. And there is a flutter file explorer application,it lists out all directories and file paths including downloads directory. I haven't checked how exactly it's been implemented. But it's really cool. 👇 FileX

abhi16180 avatar Sep 19 '22 06:09 abhi16180

Hey @lrorpilla, I've been trying to do something similar to what you've explained here but I haven't dug too deeply to solve my issues yet.

Really my use case just requires the absolute file path to be able to make a file for a video player, so I just use a non-native file picker made with Flutter that lists everything in a directory and allows navigating and changing directories. Really being able to list every file in a directory allows me to have the absolute path I need.

I'll have to take a look into filesystem_picker myself, as I am aiming to display a list of videos too but from external storage. When you use filesystem_picker to list all of your video files in a UI to select for playing, do you then experience caching when you select a file to play or are you playing using the direct path?

cnoons-cyq avatar Apr 12 '23 00:04 cnoons-cyq