7
votes

Comment puis-je éviter l'E / S du fichier réseau excessif lors de l'annexe vers un grand fichier avec .NET?

J'ai un programme qui ouvre un grand fichier binaire, ajoute une petite quantité de données à elle et ferme le fichier.

FileStream fs = File.Open( "\\\\s1\\temp\\test.tmp", FileMode.Append, FileAccess.Write, FileShare.None );
fs.Write( data, 0, data.Length );
fs.Close();


7 commentaires

Avez-vous essayé la méthode filtream.seek à la place?


Existe-t-il un scanner anti-virus actif qui fait un chèque sur accès?


Vous pouvez ajouter des informations sur votre objectif final (c'est-à-dire un système de journalisation ou outil de rapport de données) car les utilisateurs peuvent avoir des suggestions que vous n'avez peut-être pas envisagées.


@Chrisw: filemode.append Les appels recherchent en interne.


De mes tests à l'aide d'un fichier 598MB, je pense que vous avez un autre problème. Le problème n'est pas le code que vous avez posté. À première exécution, avec tous les caches système effacés, il peut prendre jusqu'à sept secondes pour écrire les 100 premiers octets sans plus que 256 ko être lu (qui est probablement en train de remplir la mémoire tampon pour le courant). Les écrit ultérieurement prenant 80ms, 24 ms et enfin 3 ms pour écrit après cela. Quelles que soient les options FileMode et FileAccess, je spécifie.


Totalement hors sujets, mais je vous suggère d'utiliser une chaîne de Verbatim lors de la gestion des chemins de fichiers, en particulier de l'UNC, de sorte que vous n'avez pas de nombre ridicule de gaspillage intégrale dans votre code. Donc, au lieu de "\\\\ s1 \\ temp \\ test.tmp" Vous vous retrouvez avec @ "\\ s1 \ temp \ test.tmp"


Amissico a raison; Il y en a plus que les informations que j'ai postées ci-dessus. J'ai fait plus d'investigation et j'ai constaté que le comportement que j'ai signalé se produit avec certains fichiers et non avec d'autres. J'ai besoin d'essayer de déterminer quelle est la différence entre les 2 cas.


7 Réponses :


0
votes

Vous pouvez mettre en cache vos données dans un tampon local et périodiquement (beaucoup moins souvent que maintenant) annexer au grand fichier. Cela économiserait sur un tas de transferts de réseau mais ... Cela augmenterait également le risque de perdre ce cache (et de vos données) au cas où votre application se bloque.

Logging (si c'est ce qu'il est) de ce type est souvent stocké dans une DB. L'utilisation d'un RDBM décent vous permettrait de poster que 100 octets de données sont très fréquemment avec des frais généraux minimes. La mise en garde Il y a le maintien d'un SGBDM.


0 commentaires

-3
votes

J'ai fait du google et j'ai examiné plus comment lire des fichiers excessivement volumineux rapidement et trouvé ce lien http://www.4guysfromrolla.com/webech/010401-1.shtml

La partie la plus intéressante Il y aurait la partie sur les octets de lecture: Outre les méthodes de Readall et Readline les plus couramment utilisées, l'objet Textstream prend également en charge une méthode de lecture (n), où n est le nombre d'octets dans le fichier / Textstream en question. En instanciant un objet supplémentaire (un objet de fichier), nous pouvons obtenir la taille du fichier à lire, puis utiliser la méthode de lecture (n) pour parcourir notre fichier. Comme il s'avère, la méthode "Lis d'octets" est extrêmement rapide par comparaison: xxx

Cette méthode pourrait ensuite être utilisée par vous pour aller à la fin du fichier et manuellement Ajoutez-le au lieu de charger l'ensemble du fichier en mode APPEND avec un fichier filtream.


1 commentaires

-1: Avez-vous remarqué qu'il s'agissait d'un article de 2001, pour VBScript, pas pour .net?



0
votes

Si vous avez accès au système ou peut-être un administrateur amical pour la machine hébergeant réellement le fichier, vous pouvez créer un petit programme d'auditeur qui se trouve sur l'autre extrémité.

Vous appelez-le simplement en passant simplement les données à écrire et que l'écriture écrite localement, en évitant le trafic de réseau supplémentaire.


0 commentaires

0
votes

L'objet de fichier dans .NET a de nombreuses méthodes statiques pour gérer ce type de chose. Je suggérerais d'essayer: xxx

Lorsque vous reflétez cette méthode, il s'avère qu'il utilise: xxx

Cette méthode de StreamWriter devrait vous permettre de Il suffit d'ajouter quelque chose à la fin (au moins c'est la méthode que j'ai vue utilisée dans chaque cas de journalisation que j'ai rencontrée jusqu'à présent).


1 commentaires

APPENDALLTEXT Retourne le vide, pas Fichier :) MSDN.MicRosoft. COM / EN-US / Bibliothèque / ...



1
votes

J'ai trouvé Ceci sur MSDN ( Createfile est appelé en interne):

Lorsqu'une application crée un fichier sur un réseau, il est préférable d'utiliser generic_read | Generic_write pour dwedesiredAccess que d'utiliser generic_write seul. Le code résultant est plus rapide, car le redirecteur peut utiliser le responsable du cache et envoyer moins de SMBA avec plus de données. Cette combinaison évite également un problème où écrire dans un fichier sur un réseau peut parfois retourner error_access_denied.

Utilisation du réflecteur, FileAccess Cartes vers DWDESIREDACCESS , il semblerait donc suggérer d'utiliser FileAccess.readwewrite au lieu de Fileaccess. Écrire .

Je n'ai aucune idée si cela aidera :)


0 commentaires

0
votes

Écrivez les données pour séparer les fichiers, puis rejoignez-les (faites-le sur la machine d'hébergement si possible) uniquement lorsque cela est nécessaire.



2
votes

0xa3 a fourni la réponse dans un confort ci-dessus. La mauvaise performance était due à une analyse de virus à accès. Chaque fois que mon programme a ouvert le fichier, le scanner Virus a lu l'intégralité du contenu du fichier pour vérifier les virus même si mon programme n'a lu aucun du contenu existant. Désactivation de l'analyse de virus sur accès a éliminé les E / S du réseau excessif et les mauvaises performances.

Merci à tout le monde pour vos suggestions.


0 commentaires