2010-04-13 4 views
0

Je n'ai pas beaucoup d'expérience avec les flux et les tampons, mais je dois le faire pour un projet, et je suis bloqué sur une exception lancée lorsque le flux que je suis en train de lire est un multiple de la taille du tampon que j'ai choisi. Permettez-moi de vous montrer:IndexOutOfRangeException lorsqu'un flux est un multiple de la taille de la mémoire tampon

Mon code commence par la lecture bufferSize (100, disons) octets du flux:

numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize); 

Ensuite, je boucle à travers une boucle while:

while (numberOfBytesRead == bufferSize) 
{ 
    BufferWriter.Write(output); 
    BufferWriter.Flush(); 
    index += bufferSize; 
    numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize); 
} 

. .. et, une fois que nous arrivons à une lecture non-bufferSize, nous savons que nous avons atteint la fin du flux et que nous pouvons continuer.

Mais si le bufferSize est 100, et le flux est 200, nous lirons les positions 0-99, 100-199, puis la tentative de lecture des erreurs 200-299. Je l'aimerais si ça renvoyait 0, mais il y a une erreur. Ce que je fais pour gérer qui est, bien, un try-catch:

catch (System.IndexOutOfRangeException) 
    numberOfBytesRead = 0; 

... qui se termine la boucle, et se termine avec succès la chose, mais nous savons tous que je ne veux pas contrôler le code flux avec gestion des erreurs.

Existe-t-il une meilleure façon (plus standard?) De gérer la lecture de flux lorsque la longueur du flux est inconnue? Cela ressemble à une petite ride dans une stratégie assez raisonnable pour lire les flux, mais je ne sais pas si je me trompe ou quoi.

Les détails de ceci (que j'ai nettoyé un peu pour la publication) sont un MySqlDataReader frappant une colonne LARGEBLOB. Il fonctionne lorsque le tampon est plus grand que le nombre d'octets retournés, ou lorsque le nombre d'octets retournés est et non un multiple de bufferSize. Parce que nous ne, dans ce cas, jeter un IndexOutOfRangeException.

Répondre

1

Vous ne devez pas être dans l'ignorance de la taille du blob:

long blobSize = dr.GetBytes(0, 0, null, 0, 0); 

... et puis, vous pouvez simplement vérifier avant de faire votre lecture pour voir que index est inférieur à blobSize . Si ce n'est pas le cas, vous savez que vous l'avez plafonné et que vous avez lu tout ce qu'il y a à lire.

2

Vous ne savez pas s'il y a une vraie question ici. Mais le code affiché est fondamentalement faux. Un flux est et non obligé de renvoyer le nombre d'octets demandé. Il peut retourner moins, et le fait souvent. Seulement quand il renvoie 0 savez-vous que vous avez atteint la fin du flux?

Cela permet à un flux d'optimiser son utilisation interne du tampon et d'améliorer le débit des E/S superposées. NetworkStream est un bon exemple.

+0

Il y avait, mais j'ai trouvé une réponse, et Henk a déplacé la réponse dans la question, donc il semble qu'il n'y en a pas. Ma question concerne la syntaxe de l'offset 0, du offset 100, puis du offset 200 dans un flux qui en a seulement 200. Obtenir l'offset 200 lançait IndexOutOfRangeException au lieu de retourner 0. Peut-être que c'est un bug dans MySqlDataReader? – dnord

+0

Ma réponse concernait un bug dans votre code. –

Questions connexes