Tengo una transmisión que contiene muchos datos. Quiero exponer solo una parte de esos datos en otra secuencia. La información que quiero extraer a menudo puede superar los 100mb. Como ya tengo stream con los datos que contiene, me parece un desperdicio copiar esos datos a otra transmisión y devolverlos. Lo que estoy buscando es una forma de referenciar los datos en la primera secuencia mientras se controla a qué cantidad puede hacer referencia la segunda secuencia. Es posibleCómo exponer una subsección de mi transmisión a un usuario
Respuesta
Debe crear su propia clase Stream que valide su posición y devuelva el subconjunto deseado.
No conozco ninguna clase incorporada que lo haga.
¿Qué tienes miedo de duplicar? Dudo que tengas algo de súper desempeño crítico, analiza tu Stream sobre la marcha y usas MemoryStream hasta que encuentres que necesitas algo más.
estaría copiando cientos de mesgs valor de los datos, y no quiero que copiar a otro lugar en la memoria. Específicamente si la persona va a solicitar múltiples secciones de cientos de megas. Además de no temer a la duplicación, es una práctica de programación reutilizar otras clases si existen. – QueueHammer
Parece que el proyecto StreamMuxer se creó con un propósito similar en mente.
Esto se ve bien. Deseo que Code Project haya trabajado con Git Hub. Probablemente un leve conflicto de intereses. – QueueHammer
Hay una buena implementación de esto por Mark Gravell detailed here. El código escrito existe:
using System.IO;
using System;
static class Program
{
// shows that we can read a subset of an existing stream...
static void Main()
{
byte[] buffer = new byte[255];
for (byte i = 0; i < 255; i++)
{
buffer[i] = i;
}
using(MemoryStream ms = new MemoryStream(buffer))
using (SubStream ss = new SubStream(ms, 10, 200))
{
const int BUFFER_SIZE = 17; // why not...
byte[] working = new byte[BUFFER_SIZE];
int read;
while ((read = ss.Read(working, 0, BUFFER_SIZE)) > 0)
{
for (int i = 0; i < read; i++)
{
Console.WriteLine(working[i]);
}
}
}
}
}
class SubStream : Stream
{
private Stream baseStream;
private readonly long length;
private long position;
public SubStream(Stream baseStream, long offset, long length)
{
if (baseStream == null) throw new ArgumentNullException("baseStream");
if (!baseStream.CanRead) throw new ArgumentException("can't read base stream");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
this.baseStream = baseStream;
this.length = length;
if (baseStream.CanSeek)
{
baseStream.Seek(offset, SeekOrigin.Current);
}
else
{ // read it manually...
const int BUFFER_SIZE = 512;
byte[] buffer = new byte[BUFFER_SIZE];
while (offset > 0)
{
int read = baseStream.Read(buffer, 0, offset < BUFFER_SIZE ? (int) offset : BUFFER_SIZE);
offset -= read;
}
}
}
public override int Read(byte[] buffer, int offset, int count)
{
CheckDisposed();
long remaining = length - position;
if (remaining <= 0) return 0;
if (remaining < count) count = (int) remaining;
int read = baseStream.Read(buffer, offset, count);
position += read;
return read;
}
private void CheckDisposed()
{
if (baseStream == null) throw new ObjectDisposedException(GetType().Name);
}
public override long Length
{
get { CheckDisposed(); return length; }
}
public override bool CanRead
{
get { CheckDisposed(); return true; }
}
public override bool CanWrite
{
get { CheckDisposed(); return false; }
}
public override bool CanSeek
{
get { CheckDisposed(); return false; }
}
public override long Position
{
get {
CheckDisposed();
return position;
}
set { throw new NotSupportedException(); }
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Flush()
{
CheckDisposed(); baseStream.Flush();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
if (baseStream != null)
{
try { baseStream.Dispose(); }
catch { }
baseStream = null;
}
}
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
- 1. Cómo exponer la propiedad Text de un control de usuario?
- 2. ¿Cómo exponer una ITemplate a través de un Control de usuario?
- 3. ¿Cómo elimino un rango (subsección) de una lista en Python?
- 4. ¿A dónde va mi suscripción de transmisión?
- 5. Cómo exponer un modelo C++ a QML
- 6. ¿Debo exponer una identificación de usuario al público?
- 7. Exponer una API de C++ a C#
- 8. Exponer una API de C++ a Python
- 9. Cómo exponer los datos a zabbix
- 10. Cómo exponer mi colección del servicio web (WCF)
- 11. Exponer una clase ISO C++ a una aplicación VB6
- 12. Exponer un controlador de eventos para los usuarios de VBScript de mi objeto COM
- 13. Exponer un objeto similar a un archivo desde Cython
- 14. Cómo exponer y generar eventos personalizados para un usuario de vb.net winforms control
- 15. Exponer ID de base de datos a la interfaz de usuario
- 16. Propiedades de Java: ¿exponer o no exponer?
- 17. C# exponer a COM - herencia de interfaces
- 18. Subsección palindrómica común más larga
- 19. LaTeX - Agregar enlaces seleccionables a una sección/subsección con un documento PDF
- 20. Exponer datos en una alimentación de átomo
- 21. ¿Cómo puedo exponer iteradores sin exponer el contenedor utilizado?
- 22. exponer y plantear el evento de un control secundario en un control de usuario en C#
- 23. Crear un complemento, exponer eventos
- 24. ¿Cómo exponer un método usando GSon?
- 25. ¿Cómo me deshago de un disco duro sin exponer mi código fuente?
- 26. transmisión RTSP a RTMP
- 27. ¿Puede un servicio web devolver una transmisión?
- 28. Convertir a transmisión desde una URL
- 29. ¿Es posible exponer un campo DateTime a través de COM?
- 30. ¿Cómo conectarse a una base de datos que requiere contraseña sin exponer la contraseña?
Así que ahora comienza mi tarea ... – QueueHammer