web-dev-qa-db-fra.com

différence entre le flux de mémoire et le flux de fichiers

Pendant la sérialisation, nous pouvons utiliser un flux de mémoire ou un flux de fichiers.

Quelle est la différence fondamentale entre ces deux? Qu'est-ce que le flux de mémoire signifie?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serilization
{
    class Program
    {
        static void Main(string[] args)
        {
            MemoryStream aStream = new MemoryStream();
            BinaryFormatter aBinaryFormat = new BinaryFormatter();
            aBinaryFormat.Serialize(aStream, person);
            aStream.Close();
        }
    }
}
42
Raghav55

Stream est une représentation d'octets. Ces deux classes dérivent de la classe Stream qui est abstraite par définition.

Comme son nom l'indique, FileStream lit et écrit dans un fichier, tandis qu'un MemoryStream lit et écrit dans la mémoire. Donc, cela concerne l'endroit où le flux est stocké.

Maintenant, cela dépend de la manière dont vous prévoyez d’utiliser les deux. Par exemple: supposons que vous vouliez lire des données binaires de la base de données, vous utiliseriez un MemoryStream. Cependant, si vous voulez lire un fichier sur votre système, vous utiliserez un FileStream.

Un avantage rapide d'un MemoryStream est qu'il n'est pas nécessaire de créer des mémoires tampons et des fichiers temporaires dans une application.

68
Enigma State

Dans sa forme la plus simple, un MemoryStream écrit des données dans la mémoire, tandis qu'un FileStream écrit des données dans un fichier.

En général, j'utilise un MemoryStream si j'ai besoin d'un flux, mais je ne veux rien frapper sur le disque, et j'utilise un FileStream lors de l'écriture d'un fichier sur le disque.

7
AllenG

Pendant qu'un flux de fichier lit dans un fichier, un flux de mémoire peut être utilisé pour lire les données mappées dans la mémoire interne de l'ordinateur. En gros, vous lisez/écrivez des flux d’octets à partir de la mémoire.

6
Tudor

Les autres réponses ici sont excellentes, mais j’ai pensé qu’une analyse très approfondie du rôle que pourrait jouer Steams pourrait être utile. L'explication ci-dessous simplifie un peu, mais j'espère que cela fait passer l'idée:

Qu'est-ce qu'un flux?

Un flux est en réalité le flux de données entre deux endroits, c'est le tuyau plutôt que le contenu de ce tuyau. 

Une mauvaise analogie pour commencer

Imaginez une usine de dessalement d’eau (quelque chose qui prélève de l’eau de mer, élimine le sel et achemine de l’eau potable vers le réseau d’eau):

L'usine de dessalement ne peut pas éliminer le sel de toute la mer en même temps (et nous ne le voudrions pas non plus… où vivrait le poisson d'eau salée?), Nous avons donc:

  • SeaStream qui aspire une quantité définie d'eau à la fois dans la plante. 
  • Cette SeaStream est connectée à la DesalinationStream pour enlever le sel 
  • Et la sortie de la DesalinationStream est connectée à la DrinkingWaterNetworkStream pour que l’eau désormais salée soit acheminée vers l’alimentation en eau potable.

OK, alors qu'est-ce que cela a à voir avec les ordinateurs?

Déplacer de gros fichiers en même temps peut être problématique

Fréquemment, en informatique, nous souhaitons déplacer des données entre deux emplacements, par ex. d'un disque dur externe à un champ binaire dans une base de données (pour reprendre l'exemple donné dans une autre réponse). Nous pouvons le faire en copiant toutes les données du fichier de l’emplacement A dans la mémoire de l’ordinateur et de là vers l’emplacement B, mais si le fichier est volumineux ou si la source ou la destination sont potentiellement non fiables, vous pouvez déplacer tout le fichier à la fois. être irréalisable ou imprudent.

Par exemple, supposons que nous voulions déplacer un fichier volumineux d'une clé USB vers un champ d'une base de données. Nous pourrions utiliser un objet 'System.IO.File' pour récupérer l'intégralité du fichier dans la mémoire de l'ordinateur, puis utiliser une connexion à la base de données pour transmettre ce fichier à la base de données.

Mais, c'est potentiellement problématique, que se passe-t-il si le fichier est plus volumineux que la RAM disponible de l'ordinateur? À présent, le fichier sera potentiellement mis en cache sur le disque dur, ce qui est lent et pourrait même ralentir l'ordinateur. 

De même, que se passe-t-il si la source de données n’est pas fiable, par ex. copier un fichier depuis un lecteur réseau avec une connexion WiFi lente et irrégulière? Essayer de copier un fichier volumineux en une fois peut être exaspérant, car vous obtenez la moitié du fichier, puis la connexion est interrompue et vous devez tout recommencer à nouveau, pour que cela puisse éventuellement échouer à nouveau.

Il peut être préférable de scinder le fichier et de le déplacer pièce par pièce

Ainsi, plutôt que de récupérer un fichier entier à la fois, il serait préférable de récupérer le fichier pièce par pièce et de transmettre chaque pièce à la destination une par une. C'est ce que fait une Stream et c'est là qu'interviennent les deux types de flux que vous avez mentionnés: 

  • Nous pouvons utiliser une variable FileStream pour récupérer les données d'un fichier pièce par pièce 
  • et l’API de base de données peut rendre disponible un point de terminaison MemoryStream que nous pouvons écrire pièce par pièce. 
  • Nous connectons ces deux "tuyaux" ensemble pour faire passer les morceaux de fichier d'un fichier à une base de données.

Même si le fichier n'était pas trop volumineux pour être conservé dans la RAM, sans flux, nous effectuions toujours un nombre ou des opérations de lecture/écriture inutiles. Les étapes que nous réalisons sont:

  1. Récupérer les données du disque (lent)
  2. Ecrire dans un objet File dans la mémoire de l'ordinateur (un peu plus vite)
  3. Lecture de cet objet File dans la mémoire de l'ordinateur (encore plus rapidement)
  4. Écrire dans la base de données (probablement lent car il y a probablement un disque dur en train de tourner à la fin de ce tube)

Les flux nous permettent de supprimer conceptuellement les deux étapes du milieu, au lieu de faire glisser le fichier entier en même temps dans la mémoire de l'ordinateur, nous prenons la sortie de l'opération pour récupérer les données et la diriger vers l'opération pour la transmettre à la base de données. .

Autres avantages des cours d'eau

Séparer la récupération des données de l'écriture des données nous permet également d'effectuer des actions entre la récupération des données et leur transmission. Par exemple, nous pourrions ajouter une étape de chiffrement ou écrire les données entrantes dans plusieurs types de flux de sortie (par exemple, dans un FileStream et un NetworkStream).

Les flux nous permettent également d’écrire du code où nous pouvons reprendre l’opération si le transfert échoue partiellement. En gardant une trace du nombre d'éléments que nous avons déplacés, si le transfert échoue (par exemple, si la connexion réseau est interrompue), nous pouvons redémarrer le flux à partir du point où nous avons reçu le dernier élément (il s'agit de la variable offset dans la méthode BeginRead ).

4
tomRedox

Ayant une expérience amère sur le sujet, voici ce que j'ai découvert. si des performances sont requises, vous devez copier le contenu d'un flux de fichiers dans un flux de mémoires. J'ai dû traiter le contenu de 144 fichiers, 528 Ko chacun et présenter le résultat à l'utilisateur. Il a fallu 250 secondes aprox. (!!!!) Lorsque je viens de copier le contenu de chaque flux de fichiers dans un flux de mémoire (méthode CopyTo) sans rien changer du tout, le temps est tombé à environ 32 secondes. Notez que chaque fois que vous copiez un flux dans un autre, le flux est ajouté à la fin du flux de destination. Vous devrez donc peut-être le «rembobiner» avant de le copier. J'espère que ça aide. 

3
ManosG

Un flux de mémoire gère les données via un tampon en mémoire. Un filestream traite les fichiers sur le disque.

2

Sérialiser des objets en mémoire n'est guère utile, à mon avis. Vous devez sérialiser un objet lorsque vous souhaitez l'enregistrer sur le disque. En règle générale, la sérialisation est effectuée à partir de l'objet (en mémoire) sur le disque, tandis que la désérialisation est effectuée à partir de l'objet sérialisé enregistré (sur le disque) vers l'objet (en mémoire).

Donc, la plupart du temps, vous voulez sérialiser sur le disque, vous utilisez donc un Filestream pour la sérialisation.

0
ThunderGr