web-dev-qa-db-fra.com

Flux de mémoire dans Java

Je recherche une implémentation de flux de mémoire en Java. L'implémentation doit être grossièrement modélisée d'après implémentation .NET .

En gros, j'aimerais avoir une classe MemoryStream qui doit utiliser des méthodes d'usine:

 class MemoryStream {
     MemoryInput createInput();
     MemoryOutput createOutput();
 }

 class MemoryInput extends InputStream {
    long position();
    void seek(long pos);
 }

 class MemoryOutput extends OutputStream {
    long position();
    void seek(long pos);
 }

Donc, une fois que j’ai une instance de la classe MemoryStream, je devrais être capable de créer simultanément des flux d’entrée et de sortie, ce qui devrait également permettre un positionnement dans n’importe quelle direction. Le flux de mémoire n'a pas besoin d'être circulaire, il devrait bien fonctionner pour les petites tailles et croître automatiquement. Le flux de mémoire doit seulement être confiné dans un processus.

Tout code de la boîte disponible?

63

ByteArrayInputStream et ByteArrayOutputStream est ce que vous recherchez.

Ce sont des implémentations des interfaces InputStream et OutputStream qui lisent et écrivent dans un tableau d'octets en mémoire. Pour ByteArrayOutputStream, le tableau s'agrandira automatiquement à mesure que vous écrivez des données dans le flux.

94
Jesper

Vous pouvez utiliser PipedInputStream et PipedOutputStream

comme ça:

PipedOutputStream outstr = new PipedOutputStream();
PipedInputStream instr = new PipedInputStream(outstr);

cela ne vous autorisera pas directement à chercher, mais vous permettra de sauter autant d'octets que vous voulez du flux d'entrée.

Sachez que chaque fois que vous écrivez dans outstr, il est bloqué jusqu'à ce que tout soit lu dans instr (c'est-à-dire: si je me souviens bien, les Streams ne tamponnent pas, mais vous pouvez les décorer avec un BufferedInputStream, alors vous n'avez pas à vous embêter. .

9
Angelo Fuchs

At-il besoin de prendre en charge les flux d’entrée et de sortie? Sinon, je voudrais simplement utiliser un ByteBuffer qui vous permet de lire/écrire des types primitifs à des emplacements aléatoires. (Jusqu'à 2 Go)

Vous pouvez partager un ByteBuffer entre un lecteur et un écrivain.

par exemple.

// 1 GB of virtual memory outside the heap.
ByteBuffer writer = ByteBuffer.allocateDirect(1024*1024*1024); 
ByteBuffer reader = writer.slice();

Vous pouvez partager la mémoire entre des threads (par exemple, un échangeur) et des processus (à l'aide de fichiers mappés en mémoire).

8
Peter Lawrey

NIO vous permet de transférer directement des données dans la mémoire du noyau - je ne suis pas sûr que cela chevauche exactement le flux de mémoire de .NET. Voici un exemple simple de mappage d'un fichier entier en mémoire pour la lecture.

4
Amir Afghani