2008-12-22 7 views
1

en utilisant le code suivant pour tenter de lire un fichier volumineux (280MB) dans un tableau d'octets à partir d'un chemin UNCIOException la lecture d'un fichier volumineux à partir d'un chemin UNC dans un tableau d'octets en utilisant je suis .NET

public void ReadWholeArray(string fileName, byte[] data) 
{ 
    int offset = 0; 
    int remaining = data.Length; 

    log.Debug("ReadWholeArray"); 

    FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); 

    while (remaining > 0) 
    { 
     int read = stream.Read(data, offset, remaining); 
     if (read <= 0) 
      throw new EndOfStreamException 
       (String.Format("End of stream reached with {0} bytes left to read", remaining)); 
     remaining -= read; 
     offset += read; 
    } 
} 

Ceci explose avec l'erreur suivante.

System.IO.IOException: Insufficient system resources exist to complete the requested 

Si je lance cette aide d'un chemin local, il fonctionne très bien, dans mon cas de test le chemin UNC est en fait la pointe vers la boîte locale.

Une réflexion sur ce qui se passe ici?

Répondre

4

Je pense que quelque chose de plus bas essaie de lire dans un autre tampon, et lire 280 Mo en une fois échoue. Il peut y avoir plus de tampons requis dans le cas du réseau que dans le cas local. Je voudrais lire environ 64 Ko à la fois au lieu d'essayer de lire tout le lot en une seule fois. C'est suffisant pour éviter une trop grande quantité de découpage, mais cela évitera d'avoir besoin de tampons énormes.

Personnellement, j'ai tendance à simplement lire jusqu'à la fin du flux plutôt que de supposer que la taille du fichier restera constante. Voir this question pour plus d'informations.

+0

Une raison particulière pour laquelle vous utilisez 4 pages de mémoire pour vos tampons? –

+0

@Robert Davis: La taille importante n'est pas * les pages * memory * mais les tampons * IO *. Si vous lisez tellement que cela nécessite plusieurs requêtes d'E/S, c'est un peu inutile - si vous lisez si peu que cela correspond à une requête avec de l'espace à perdre, c'est un gaspillage dans l'autre sens. Mon expérience est que 64K fait souvent un bon compromis, mais cela dépend exactement de ce qui se passe aux niveaux inférieurs. –

0

Il semble que le tableau n'ait pas été créé avec une taille suffisante. Quelle taille d'un tableau est allouée avant d'être passé? Ou supposiez-vous que la fonction Read réallouerait le tableau de données si nécessaire? Ça ne va pas. Edit: Euh, peut-être pas, je viens de remarquer l'exception que vous avez. Pas sûr maintenant.

1

En outre, le code tel qu'il est écrit doit placer le FileStream dans un bloc using. Ne pas disposer des ressources est une raison très possible de recevoir "Ressources système insuffisantes":

public void ReadWholeArray(string fileName, byte[] data) 
{ 
    int offset = 0; 
    int remaining = data.Length; 

    log.Debug("ReadWholeArray"); 

    using(FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) 
    { 
     while (remaining > 0) 
     { 
      int read = stream.Read(data, offset, remaining); 
      if (read <= 0) 
       throw new EndOfStreamException 
        (String.Format("End of stream reached with {0} bytes left to read", remaining)); 
      remaining -= read; 
      offset += read; 
     } 
    } 
} 
+0

+1. Wow, l'OP a plus d'un an et vous l'avez remarqué. La taille de la mémoire tampon était probablement le problème majeur mais cela en deviendrait un. –

+0

@Kevin: J'ai fait un montage de la question (à cause d'un montage de Jon Seigal), et ça m'a sauté aux yeux. Leçon difficile à apprendre. –

Questions connexes