Когда вы возвращаете содержимое Uri в OnActivityResult
, у вас есть временное разрешение (и, следовательно, доступ для записи) к этому Uri, так что вы можете открыть дескриптор файла на основе участка в режиме записи, создать поток вывода из этогодескриптор файла посылки и запись в него всего, что вам нужно.
Пример записи потока активов в файл, выбранный пользователем:
protected async override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
if (resultCode == Result.Ok && requestCode == 43)
{
var buffer = new byte[1024];
using (var pFD = ContentResolver.OpenFileDescriptor(data.Data, "w"))
using (var outputSteam = new FileOutputStream(pFD.FileDescriptor))
using (var inputStream = Assets.Open("somePicture.png"))
{
while (inputStream.CanRead && inputStream.IsDataAvailable())
{
var readCount = await inputStream.ReadAsync(buffer, 0, buffer.Length);
await outputSteam.WriteAsync(buffer, 0, readCount);
}
}
}
base.OnActivityResult(requestCode, resultCode, data);
}
Обновление (производительность):
Просто к сведению, если вы сохраняете / потоковые большие файлы, избегайте асинхронных версий чтения и записи в потоках и просто раскрутите один поток (или используйте один из пула потоков через Task.Run).
Примечание: это будет всегда быстрее из-за всех асинхронных / ожидающих накладных расходов и примерно как обычно, как я бы это делал (обычно быстрее в 2 раза (+) в зависимости от размера файла).
if (resultCode == Result.Ok && requestCode == 43)
{
await Task.Run(() =>
{
// Buffer size can be "tuned" to enhance read/write performance
var buffer = new byte[1024];
using (var pFD = ContentResolver.OpenFileDescriptor(data.Data, "w"))
using (var outputSteam = new FileOutputStream(pFD.FileDescriptor))
using (var inputStream = Assets.Open("her.png"))
{
while (inputStream.CanRead && inputStream.IsDataAvailable())
{
var readCount = inputStream.Read(buffer, 0, buffer.Length);
outputSteam.Write(buffer, 0, readCount);
}
}
});
}