2009-08-13 3 views
2

Je travaille actuellement à un programme qui transfère des fichiers via FTP. J'envoie les fichiers en binaire car avec l'ASCII je ne peux pas envoyer de caractères spéciaux.Comment optimiser mon BinaryWriter?

Voici mon code actuellement:

using(BinaryReader bReader = new BinaryReader(srcStream)) 
    using (BinaryWriter bWriter = new BinaryWriter(destStream)) 
    { 
     Byte[] readBytes = new Byte[1024]; 
     for(int i = 0; i < bReader.BaseStream.Length; i += 1024) 
     { 
      readBytes = bReader.ReadBytes(1024); 
      bWriter.Write(readBytes); 
     } 
    } 

Mes problèmes avec ce code sont:

  1. Il fonctionne vraiment lent, est-il un moyen d'optimiser?
  2. La façon dont je demande EOF (EndOfFile) semble être très étrange, y at-il une autre option d'élégance?

Merci beaucoup: D

+0

Après la mise en œuvre de la solution de Jon et publié Gbegen, je reçois toujours un message d'erreur « Requête non prise ». – Camal

Répondre

9

Pourquoi utilisez-vous BinaryReader et BinaryWriter du tout? Pourquoi demandez-vous à plusieurs reprises pour la longueur? Voici une méthode que j'ai posté un tas de fois maintenant:

public static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8192]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

qui utilise un tampon 8K, mais vous pouvez changer cela évidemment. Oh, et il réutilise le tampon plutôt que de créer un nouveau tableau d'octets à chaque fois, ce que fera votre code :) (Vous n'avez pas besoin d'allouer le tableau d'octets pour commencer - vous auriez pu déclarer readBytes au point de l'appel à bReader.ReadBytes.)

+1

Première chose d'abord, merci Jon. Mais maintenant, je suis très confus: D Je suis assez nouveau pour travailler avec Streams et je pensais que je ne peux écrire avec BinaryWriter en mode binaire. Ainsi, les flux ont des méthodes de lecture/écriture. Et agian j'ai appris quelque chose: D Mais juste au cas où un fichier a une taille de "0" mais je veux transférer ce fichier aussi. Si cela fonctionne pour moi? – Camal

+0

Cela fonctionnera bien, oui - le premier appel à Read renverra 0, et vous quitterez la boucle. BinaryReader/BinaryWriter sont des classes d'utilitaires pour lire et écrire des primitives, etc. sur des flux. Les flux eux-mêmes ne sont que des sources binaires et des destinations pour les données - StreamReader/StreamWriter décodant/encodant le texte. –

+0

J'aimerais quand même savoir pourquoi 'BinaryWriter.BaseStream' est super lent. N'est-il pas supposé renvoyer un champ stream sauvegardé par le constructeur? –

2

Je pense que vos problèmes de performance proviennent de deux endroits. Vous appelez bReader.BaseStream.Length à chaque fois via la boucle et votre appel à bReader.ReadBytes() alloue un nouveau tableau d'octets à chaque fois.

Je ne pense pas aussi BinaryReader et BinaryWriter sont nécessaires que vous n'utilisez pas leurs fonctions pour la lecture et l'écriture d'autres types de tableaux d'octets, qui sont déjà pris en charge dans les cours d'eau sous-jacents par Stream.Read() et Stream.Write().

Je ferais cela comme:

byte [] buffer = new byte[1024]; 
int bytesRead; 
while ((bytesRead = srcStream.Read(buffer, 0, buffer.Length)) != 0) 
{ 
    dstStream.Write(buffer, 0, bytesRead); 
} 
Questions connexes