[Android] Stream.Length is not supported from asset
See original GitHub issueDescription
It works well on Windows.
async Task LoadMauiAsset()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
using var reader = new StreamReader(stream);
var contents = reader.ReadToEnd();
}
This is a sample from AboutAssets.txt file which is a part of the basic MAUI app template.
When opening any other file than a text file, I am copying the stream to a MemoryStream
using stream.CopyTo
method to be able to get byte[]
- e.g. open image file embedded resource as byte[]
for MAUI Blazor application to display it using <img>
tag using base64
encoding. Btw the original stream returns just string
(why?) are embedded resources supposed to be string content by default?
Allocating the specified amount of bytes for the MemoryStream
to prevent memory fragmentation is not possible - stream.Length
doesn’t work on the original stream.
Steps to Reproduce
var stream = await FileSystem.OpenAppPackageFileAsync(filePath);
var ms = new MemoryStream((int)stream.Length); //crash -> Length not supported
Version with bug
Release Candidate 3 (current)
Last version that worked well
Unknown/Other
Affected platforms
Android, I was not able test on other platforms
Affected platform versions
probably all
Did you find any workaround?
No response
Relevant log output
No response
Issue Analytics
- State:
- Created a year ago
- Comments:9 (4 by maintainers)
Top GitHub Comments
@janseris as far as I ever researched, on Android it is not possible in general to get the size of an asset, and you just have to open it and read to the end and count the bytes. I tried reading up on it again and it seems that some people have found ways, such as using Android AssetManager and calling the
Open(String, Access)
overload likeassetManager.Open("the_resource", Access.Random)
, and then perhaps the stream’s Length becomes available? I know on Android it gets tricky because assets are usually compressed, so it doesn’t know the length automatically (internally it knows the compressed length, but that isn’t useful). I’m still surprised that it doesn’t store the uncompressed length as metadata because it seems to me that would be useful quite often.But, to be honest, I’d be a bit surprised if that
Open()
API actually worked, because a long time ago when I was trying to get the stream length I felt like I’d tried every option, and nothing worked. But I don’t remember exactly what I did or didn’t try, so maybe this does work. And if it does work, perhaps we should internally use that API in various places in .NET MAUI.I suggest that if you can determine whether that API actually works as expected on .NET MAUI, we’d certainly consider changing to use it in several places.
@mattleibow the point of this issue is getting byte[] size before reading it to be able to allocate without memory fragmentation. How can this be done for files in app package? Another thing is reading the file without needing double of the amount in memory (without stream copyto). Imagine a 100 MB file with static map data.