Fichiers mappés en mémoire en Java
J'ai essayé d'écrire quelques très rapide de code Java qui doit faire beaucoup d'I/O. je suis en utilisant un fichier mappé en mémoire qui renvoie un ByteBuffer:
public static ByteBuffer byteBufferForFile(String fname){
FileChannel vectorChannel;
ByteBuffer vector;
try {
vectorChannel = new FileInputStream(fname).getChannel();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return null;
}
try {
vector = vectorChannel.map(MapMode.READ_ONLY,0,vectorChannel.size());
} catch (IOException e) {
e.printStackTrace();
return null;
}
return vector;
}
Le problème que je rencontre est que le ByteBuffer .array (), méthode (qui doit retourner un byte[] tableau) ne fonctionne pas pour les fichiers en lecture seule. Je veux écrire mon code pour qu'il fonctionne avec de la mémoire tampon construit dans la mémoire et les tampons de lecture à partir du disque. Mais je ne veux pas de l'emballage de tous mes tampons un ByteBuffer.wrap (), car je crains que cela va ralentir les choses. Donc, j'ai écrit deux versions de tout, celui qui prend un byte[], l'autre qui prend un ByteBuffer.
Dois-je juste envelopper tout? Ou devrais-je double tout écrire?
OriginalL'auteur vy32 | 2009-06-21
Vous devez vous connecter pour publier un commentaire.
Personne n'a réellement vérifier pour voir si
ByteBuffers
créé par mappage de mémoire de soutien en invoquant.array()
en premier lieu, quel que soit readonly/readwrite?De mon fureter partout, aussi loin que je peux dire, la réponse est PAS. Un
ByteBuffer
la capacité de retourner directementbyte[]
tableau viaByteBuffer.array()
est goverened par la présence deByteBuffer.hb
(byte[]
), qui est toujours défini comme null si uneMappedByteBuffer
est créé.Qui suce plutôt pour moi, parce que j'espérais faire quelque chose de similaire à ce que l'auteur de la question a voulu faire.
Un
byte[]
doit être sur le tas. Un mappés en mémoire bloc de mémoire doit être à l'extérieur du tas. Ce serait bien si la distinction d'être transparentes, mais je préfère utiliser le getLong/putLong méthode d'un ByteBuffer de toute façon (ils sont beaucoup plus rapides avec l'aide maternelle de la commande)OriginalL'auteur Trevor Harrison
Il est toujours bon de ne pas réinventer la roue.
Apache a fourni une belle bibliothèque pour effectuer des opérations d'e/S. Jetez un oeil à http://commons.apache.org/io/description.html
Voici le scénario qu'il sert. Supposons que vous avez des données que vous auriez
préfère garder en mémoire, mais vous ne savez pas à l'avance combien de données
il va y être. Si il y a trop de choses, vous voulez écrire sur le disque
au lieu d'accaparer la mémoire, mais vous ne voulez pas écrire sur le disque jusqu'à ce que vous
besoin de le faire, parce que le disque est lent et est une ressource qui a besoin de suivi pour
de nettoyage.
Ainsi, vous créez un tampon temporaire et de commencer à écrire. Si /lorsque vous
atteindre le seuil de ce que vous souhaitez garder en mémoire, vous aurez besoin de
créer un fichier, écrire ce qui est dans le tampon de ce fichier et d'écrire tous les
ultérieure des données dans le fichier au lieu de la mémoire tampon.
C'est ce que DeferredOutputStream fait pour vous. Il cache tous les déconner
autour du point de commutation. Tout ce que vous devez faire est de créer l'
différés flux en premier lieu, configurer le seuil, et puis juste
écrivez le contenu de votre coeur.
EDIT: je viens de faire une petite recherche à l'aide de google et trouvé ce lien:
http://lists.apple.com/archives/java-dev/2004/Apr/msg00086.html
(La vitesse de l'éclair fichier en lecture/écriture). Très impressionnante.
En fait, je suis juste à la recherche rapide de façons de le faire moi, mais je suis aussi à la recherche de façons de traiter les tampons avec le montant minimum de tampon de copie.
Vous référez-vous
DeferredOutputStream
de Apache commons-io? Je ne peux pas trouver une telle classe dans la Javadoc pour v2.3 & v2.2.OriginalL'auteur Gaurav Saini
Emballage byte[] ne pas ralentir les choses...il n'y aura pas grand éventail de copies ou d'autres petits performances maux. À partir de la documentation Javadoc: java.nio.ByteBuffer
.wrap()
Ça me paraît terriblement "fine" qui concerne les performances, et les odeurs comme l'optimisation prématurée pour moi. La JVM est bon sur des trucs comme ça. De référence pour le prouver à vous-même d'une façon ou de l'autre.
En fait, je suis en train de faire la criminalistique informatique, le traitement des téraoctets d'informations. Dans mon expérience, à la date de la JVM n'est pas optimisé autant que je l'aurais espéré.
Avez-vous des repères indiquant une dégradation de la performance en raison de l'appel de la méthode ci-dessus? Je ne peux pas imaginer qu'il soit plus que mineur, et aurait pensé qu'il y aurait d'autres domaines plus mûr pour le réglage. En prenant une approche scientifique de ces choses emporte sur tout. Hmmm...peut enquêter sur les cours du week-end juste pour le fun! 🙂
Aussi, je pose la question, quelle est la version de Java que vous utilisez? Chaque version majeure a constaté des améliorations dans les performances de la JVM. Si votre tâche est que la performance sensible, vous devriez être sur la version 6 de Java.
OriginalL'auteur Stu Thompson
À l'aide de la ByteBuffer.wrap() la fonctionnalité ne pas imposer un lourd fardeau. Il alloue un objet simple et initialise un peu entiers. La rédaction de votre algorithme contre ByteBuffer est donc votre meilleur pari si vous avez besoin de travailler avec lire uniquement les fichiers.
OriginalL'auteur Jherico