question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Android] Stream.Length is not supported from asset

See original GitHub issue

Description

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:closed
  • Created a year ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Eiloncommented, May 25, 2022

@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 like assetManager.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.

0reactions
janseriscommented, Nov 13, 2022

@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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Stream.Length throws NotSupportedException
Stream.Length only works on Stream implementations where seeking is available. You can usually check to see if Stream.CanSeek is true.
Read more >
Why the asset bundle slow in StreamingAssets on android ...
I am loading the resource in Editor using AssetDatabase is fast, but when I export the assetbundle, copy them into StreamingAssets, ...
Read more >
Can't use json file from StreamingAssets on Android and iOS
(I have 0 experience on json and streaming assets.) The following is the script in my project. I'm really not sure how to...
Read more >
Support different screen sizes
Checklist for supporting different window size classes. Responsive design ... Window size classes are not intended for isTablet-type logic.
Read more >
Play Asset Delivery
The total download size limit for all asset packs in an Android App Bundle is 2 GB. You can use up to 50...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found