Hay una manera de convertir un System. IO. Stream a un Windows.Almacenamiento.Flujo.IRandomAccessStream?
En Windows 8; Me gustaría pasar el contenido de un MemoryStream a una clase que acepte un parámetro de tipo Windows.Almacenamiento.Flujo.IRandomAccessStream. ¿Hay alguna manera de convertir este MemoryStream a un IRandomAccessStream?
7 answers
Para usar las extensiones: debe agregar "usando System.IO"
En Windows8, los tipos.NET y WinRT generalmente se convierten a/desde tipos compatibles bajo el capó, por lo que no tiene que preocuparse por ello.
Para flujos, sin embargo, hay métodos auxiliares para convertir entre flujos WinRT y. NET: Para convertir de secuencias WinRT - > secuencias. NET:
InMemoryRandomAccessStream win8Stream = GetData(); // Get a data stream from somewhere.
System.IO.Stream inputStream = win8Stream.AsStream()
Para la conversión de secuencias. NET - > secuencias WinRT:
Windows.Storage.Streams.IInputStream inStream = stream.AsInputStream();
Windows.Storage.Streams.IOutputStream outStream = stream.AsOutputStream();
ACTUALIZAR: 2013-09-01
Que no se dice que Microsoft no escucha a su comunidad de desarrolladores;)
En el anuncio de para. NET FX 4.5.1, Microsoft afirma que:
Muchos de ustedes han estado queriendo una forma de convertir una transmisión. NET a un IRandomAccessStream de tiempo de ejecución de Windows. Vamos a llamarlo un método de extensión AsRandomAccessStream. No pudimos obtener esta función en Windows 8, pero fue una de nuestras primeras adiciones a Windows 8.1 Preview.
Ahora puedes escriba el siguiente código, para descargar una imagen con HttpClient, cárguela en una BitmapImage y luego establezca como fuente para un control de imagen Xaml.
//access image via networking i/o
var imageUrl = "http://www.microsoft.com/global/en-us/news/publishingimages/logos/MSFT_logo_Web.jpg";
var client = new HttpClient();
Stream stream = await client.GetStreamAsync(imageUrl);
var memStream = new MemoryStream();
await stream.CopyToAsync(memStream);
memStream.Position = 0;
var bitmap = new BitmapImage();
bitmap.SetSource(memStream.AsRandomAccessStream());
image.Source = bitmap;
HTH.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-01 18:40:47
Encontró una solución más elegante:
public static class MicrosoftStreamExtensions
{
public static IRandomAccessStream AsRandomAccessStream(this Stream stream)
{
return new RandomStream(stream);
}
}
class RandomStream : IRandomAccessStream
{
Stream internstream;
public RandomStream(Stream underlyingstream)
{
internstream = underlyingstream;
}
public IInputStream GetInputStreamAt(ulong position)
{
//THANKS Microsoft! This is GREATLY appreciated!
internstream.Position = (long)position;
return internstream.AsInputStream();
}
public IOutputStream GetOutputStreamAt(ulong position)
{
internstream.Position = (long)position;
return internstream.AsOutputStream();
}
public ulong Size
{
get
{
return (ulong)internstream.Length;
}
set
{
internstream.SetLength((long)value);
}
}
public bool CanRead
{
get { return this.internstream.CanRead; }
}
public bool CanWrite
{
get { return this.internstream.CanWrite; }
}
public IRandomAccessStream CloneStream()
{
throw new NotSupportedException();
}
public ulong Position
{
get { return (ulong)this.internstream.Position; }
}
public void Seek(ulong position)
{
this.internstream.Seek((long)position, SeekOrigin.Begin);
}
public void Dispose()
{
this.internstream.Dispose();
}
public Windows.Foundation.IAsyncOperationWithProgress ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
{
return this.GetInputStreamAt(this.Position).ReadAsync(buffer, count, options);
}
public Windows.Foundation.IAsyncOperation FlushAsync()
{
return this.GetOutputStreamAt(this.Position).FlushAsync();
}
public Windows.Foundation.IAsyncOperationWithProgress WriteAsync(IBuffer buffer)
{
return this.GetOutputStreamAt(this.Position).WriteAsync(buffer);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-03 13:03:50
Después de experimentar, encontré que el siguiente código estaba funcionando.
using System;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage.Streams;
partial class MainPage
{
public MainPage()
{
var memoryStream = new MemoryStream(new byte[] { 65, 66, 67 });
ConvertToRandomAccessStream(memoryStream, UseRandomAccessStream);
InitializeComponent();
}
void UseRandomAccessStream(IRandomAccessStream stream)
{
var size = stream.Size;
} // put breakpoint here to check size
private static async void ConvertToRandomAccessStream(MemoryStream memoryStream,
Action<IRandomAccessStream> callback)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
var dw = new DataWriter(outputStream);
var task = new Task(() => dw.WriteBytes(memoryStream.ToArray()));
task.Start();
await task;
await dw.StoreAsync();
var success = await outputStream.FlushAsync();
callback(randomAccessStream);
}
}
ACTUALIZACIÓN: También probé la implementación del método más elegante:
private static void ConvertToRandomAccessStream(MemoryStream memoryStream,
Action<IRandomAccessStream> callback)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
RandomAccessStream.Copy(memoryStream.AsInputStream(), outputStream);
callback(randomAccessStream);
}
Extrañamente, no funciona. Cuando llamo stream.Size
más tarde, obtengo cero.
ACTUALIZACIÓN Cambié la función para devolver el IRandomAccessStream en lugar de usar la función callback
public static async Task<IRandomAccessStream> ConvertToRandomAccessStream(MemoryStream memoryStream)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
var dw = new DataWriter(outputStream);
var task = new Task(() => dw.WriteBytes(memoryStream.ToArray()));
task.Start();
await task;
await dw.StoreAsync();
await outputStream.FlushAsync();
return randomAccessStream;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-03 01:10:22
No hay un método integrado en Windows 8. Para Windows 8.1 hemos añadido una secuencia.Método de extensión AsRandomAccessStream ():
internal static IRandomAccessStream ToRandomAccessStream(byte[] array)
{
MemoryStream stream = new MemoryStream(array);
return stream.AsRandomAccessStream();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-28 00:21:11
Nada de lo anterior funciona para mí hoy (tal vez algunos cambios en la API desde que se publicaron las respuestas). La única manera que funciona es
IRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();
using (var inputStream = stream.AsInputStream())
{
await RandomAccessStream.CopyAsync(inputStream, inMemoryStream);
}
inMemoryStream.Seek(0);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-12 10:17:06
Este fragmento de código convierte un flujo (stream
) en un InMemoryRandomAccessStream (ims
) que implementa IRandomAccessStream
. El truco es que CopyTo tiene que ser llamado en un hilo de fondo.
InMemoryRandomAccessStream ims = new InMemoryRandomAccessStream();
var imsWriter = ims.OpenWrite();
await Task.Factory.StartNew(() => stream.CopyTo(imsWriter));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-14 16:46:28
Echa un vistazo a este enlace:
Cómo Convertir Una Matriz De Bytes A IRandomAccessStream
También da ejemplos y una implementación de un constructor de matriz de bytes (y uno para flujos.NET), útil si desea usar los métodos SetSource
o SetSourceAsync
de la clase BitmapImage
(como en mi caso).
Espero que esto ayude a alguien...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-28 08:17:30