2012-10-10 3 views
0

Possible en double:
Best way to copy between two Stream instances - C#Copier des fichiers en utilisant C#

Je sais que je peux utiliser File.Copy mais, je suis plus intéressé à faire un chemin plus long tour, juste pour un but éducatif. Maintenant, l'approche que je veux discuter est d'utiliser StreamReader et StreamWriter (ou FileStreams). Dans mon esprit, je voudrais lire le fichier (en tant que binaire) dans la mémoire, puis écrire le fichier au nouvel emplacement. Cela me semble être un potentiel d'erreurs puisque
1) le fichier entier est chargé en mémoire (et je ne saurais pas quelle est la taille du fichier) et
2) cela prendrait du temps par rapport à quelque chose comme copier un octet , collez un octet (ce que je suppose être le fonctionnement du streaming) car nous devrons attendre que le fichier entier soit stocké en mémoire avant même que le collage commence.

Alors, un long chemin à demander, comment je diffuser un travail de copier-coller?

+2

C'est assez facile: lisez un morceau, écrivez un morceau jusqu'à EOF. Mais qu'avez-vous essayé? – CodeCaster

+0

ce que vous avez essayé ???????????? –

+0

@raman J'ai essayé quelques choses et j'ai fini par me mettre en boucle - je commence alors à regarder en ligne et chaque autre réponse suggère un itinéraire différent.Le problème avec les différentes routes est que je ne sais pas si les routes sont bonnes ou pas, d'où le mieux à demander sur ce site où d'autres personnes peuvent commenter sur ces suggestions – Dave

Répondre

4

Donc, un long chemin à demander, comment je diffuser un travail de copier-coller?

Au lieu de lire soit chaque octet séparément dans la mémoire ou l'ensemble du fichier en mémoire, vous iriez à mi-chemin entre - créer un tampon, par exemple 32 Ko et demandez au flux d'entrée de lire autant de données. Écrivez cependant beaucoup d'octets que vous avez lus, puis répétez jusqu'à ce qu'il n'y ait plus de données à lire. Donc, quelque chose comme:

public void Copy(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[32 * 1024]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0) 
    { 
     output.Write(buffer, 0, bytesRead); 
    } 
} 

Ce n'est pas aussi efficace qu'il pourrait potentiellement, comme vous n'êtes pas lire et écrire en même temps. IO Asynchronous fixerait, mais le rendre beaucoup plus compliqué - et il est tout à fait possible que le système d'exploitation sera assez intelligent pour continuer à lire pendant que vous écrivez quand même ...

Notez que vous voudrez certainement utiliser Stream plutôt que TextReader/TextWriter sauf si vous étiez en train de lire du texte.

+0

Parfait, exactement le type de réponse que j'espérais (et votre livre est arrivé aujourd'hui d'Amazon :)) – Dave

+0

_ "exactement le type de réponse que j'espérais" _ - puis incorporer vos pensées dans votre question suivante. Nous ne pouvons pas deviner ce que vous avez déjà pensé. ;-) – CodeCaster

+0

@DaveRook: Voir l'édition de l'exemple de code - qui, ironiquement, est à peu près la même que celle que vous trouverez dans le livre quelque part :) –

1
  1. Créer un fichier de destination vide
  2. Lire un tampon à partir du fichier source (permet de dire 1024 octets)
  3. Ecrivez le tampon au fichier destionation
  4. Répéter l'opération avec 2 jusqu'à ce que tout soit fait
2

Vous pouvez lire/écrire le fichier par blocs de 1 Mo (par exemple). MSDN has an example qui montre comment faire cela.

Questions connexes