Riepilogo
Sto sviluppando un lettore di file in formato WAV con WinRT, e per questo ho bisogno di leggere quantità casuali di strutture costituite da tipi fondamentali come int
, uint
, float
e così via.
Indietro nello sviluppo del desktop ci si potrebbe basare su BinaryReader , ora in WinRT è stato sostituito da DataReader che funziona in modo asincrono.
problema
Non riesco a capire come usare questa nuova classe da ora, un buffer intermedio deve essere compilato usando LoadAsync () , metodi di lettura delle chiamate precedenti come ReadInt32 () .
Al contrario, con il vecchio BinaryReader non c'era la nozione di dover riempire un buffer intermedio prima di leggere le primitive dalla sorgente.
Ogni esempio che ho visto sul web sono "ingenui" nel senso che leggono interamente il flusso sorgente in memoria, ma nel mio caso un file WAV si trova nell'intervallo di cento megabyte e forse gigabyte.
Ho abbozzato i seguenti metodi di supporto che pre-riempiono il buffer intermedio con solo ciò che è necessario e in pratica mi libera dal chiamare sistematicamente LoadAsync
ogni volta prima di leggere qualcosa dallo stream:
internal static class DataReaderExtensions
{
public static async Task<string> ReadStringAsync(this DataReader reader, uint length)
{
await LoadAsync(reader, length);
return reader.ReadString(length);
}
private static async Task LoadAsync(DataReader reader, uint length)
{
var u = await reader.LoadAsync(length);
if (u < length) throw new InvalidOperationException();
}
}
Ma non sono completamente sicuro se sia la strada da percorrere quando si utilizza DataReader
.
Domanda
Come si suppone di pre-riempire il buffer intermedio nel mio caso?
- si dovrebbe caricare solo la quantità necessaria come mostrato sopra?
- o si dovrebbe caricare una dimensione costante (ad esempio 65536 byte), tenere traccia della posizione di lettura quindi eventualmente pre-scaricare di più su richieste più grandi? (sostanzialmente avvolgendo
DataReader
in una classe helper)
Modifica
Guardando il codice sorgente di BinaryReader non sembra esserci alcun tipo di magic dietro la scena, ovvero i byte vengono scaricati su richiesta. Quindi per il mio caso, anche se sembra un po 'sciocco leggere le primitive in modo asincrono, immagino sia il modo più semplice e sicuro per farlo; a differenza del wrapping di DataReader
, del rilevamento della posizione di lettura, della gestione di un buffer intermedio e infine l'impossibilità di derivarne come tipi WinRT pubblici devono essere sigillati ... non è sicuro che ne valga la pena per il risultato.
Purtroppo le origini degli assembly WINMD non sono disponibili, sarebbe stato piuttosto interessante vedere come lo fanno in Microsoft, poiché questi tipi più recenti possono essere utilizzati come tipi precedenti, con questi metodi di estensione .