2010-09-06 20 views
6

Uso un BinaryReader (MemoryStream(MyByteArray)) per leggere record di dimensioni variabili ed elaborarli tutti in memoria. Funziona bene fino a quando il mio puntatore, che è nell'array, ha una dimensione inferiore a circa 1,7 GB. Dopo di ciò (che è la dimensione massima di un intero nel mio sistema a 64 bit) non è possibile creare un bytearray più grande, anche se ho abbastanza memoria reale. Quindi la mia soluzione è stata quella di leggere il filmato e dividerlo in più array di byte.Lettura da un enorme MemoryStream in C#

Ora, tuttavia, non riesco a "leggere" oltre i limiti dell'array di byte e, poiché i miei dati sono in un formato variabile, non posso garantire che gli array di byte finiscano sempre su un intero record.

Questo deve essere un problema comune per le persone che elaborano set di dati molto grandi e che hanno ancora bisogno di velocità.

Come posso gestire questo problema?

+0

È necessario impedire che un array di byte di queste dimensioni sia caricato in memoria per cominciare. Non è possibile implementare una soluzione di streaming in cui si caricano solo parti dell'array in memoria (un buffer)? Hai bisogno di un accesso casuale a questi byte? Oppure puoi utilizzare una soluzione forward-only in cui puoi leggere lo stream dall'inizio alla fine mentre lo elabori (e senza voltarti indietro). Da dove viene questa matrice di byte? Un file, un servizio web, ...? –

risposta

4

Modifica: Leggendo le basi, mi rendo conto che i file mappati in memoria potrebbero essere più lenti del normale I/O per l'accesso sequenziale.

Hai provato qualcosa di simile:

var stream = new FileStream("data", 
    FileMode.Open, 
    FileAccess.Read, 
    FileShare.Read, 
    16 * 1024, 
    FileOptions.SequentialScan) 

var reader = new BinaryReader(stream); 

Se i dati risiede in un file ed è possibile utilizzare NET 4.0 considerare l'utilizzo di MemoryMappedFile.

È quindi possibile utilizzare uno MemoryMappedViewStream per ottenere uno streaming o utilizzare uno MemoryMappedViewAccessor per ottenere un'interfaccia simile a BinaryReader.

+1

Sì. L'ho provato - sfortunatamente i MemoryMappedFiles sono davvero molto lenti. – ManInMoon

2

Per i flussi eccessivamente grandi, non si deve cercare di dumping in MemoryStream - usare cose come FileStream invece, e parlare direttamente su disco. Il buffering integrato è di solito sufficiente, oppure puoi modificarlo con cose come BufferedStream (ma raramente ho avuto bisogno di farlo - ma poi tendo ad includere il mio buffer di elaborazione dati).

si potrebbe anche prendere in considerazione le cose come la compressione o dati densamente, e serializzatori progettati per funzionare da lo streaming record, piuttosto che la creazione di un intero grafico in una sola volta (anche se da quando si parla BinaryReader, si può già facendo questo altamente manualmente, quindi questo potrebbe non essere un problema).

+0

Sì. È compresso - wuite in modo efficiente e lo ho unserialize con la mia logica. Ma leggere dal disco è troppo lento. Tutto - io uso l'elaborazione parallela di questo enorme file di dati e averlo su disco potrebbe cogliere ogni tipo di contesa. – ManInMoon

+0

L'uso di una memoriaStrea, tutto in memoria, funziona perfettamente per me, tranne che ora i miei dati non hanno superato questa dimensione massima arbitaria di un bytearray. – ManInMoon

+0

Spero che tu abbia finito di leggere prima le tue 300 email, altrimenti nessun dessert (SO) per te! –