IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment partager un fichier dans un processus?


Sujet :

C#

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut Comment partager un fichier dans un processus?
    Bonjour.

    J'ai du mal à trouver des infos/précisions, sur comment partager l'acces à un fichier uniquement dans un processus.

    Dit autrement.
    J'ai dans mon appli, 2 FileStream, l'un pour ecrire, l'autre pour lire.
    Je veux que les 2 puissent acceder au meme fichier en meme temps, mais je ne veux pas qu'une autre appli puisse ouvrir le ficher en question tant que je n'ai pas fini mon job.

    J'ai fais plein d'essais avec le parametre FileShare, mais il n'y a rien à faire, mon Reader leve une exception disant que le fichier est deja utilisé par un autre processus.

    petit exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    m_writer = new FileStream(m_destFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, buffersize, true);
    //Entre temps m_writer a écrit un block, et est peut etre en train d'ecrire le block suivant...
    m_reader = new FileStream(m_destFile, FileMode.Open, FileAccess.Read, FileShare.Read, size, true);
    Dans cet exemple l'exception est levée lors de la définition de m_reader, pourtant FileShare a été définit à Read dans le Writer qui est le premier à utiliser le fichier; vu que reader est défini avec un FileAccess.Read, je ne comprends pas pourquoi j'obtiens cette erreur.

  2. #2
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2007
    Messages : 257
    Par défaut
    Bonsoir,
    Je pense que tu devrais chercher du coté de l'utilisation d'un lock.Il y a des classes pour cela en C#, je ne sais plus exactement lesquels.

  3. #3
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Citation Envoyé par Miko95 Voir le message
    Je pense que tu devrais chercher du coté de l'utilisation d'un lock.Il y a des classes pour cela en C#, je ne sais plus exactement lesquels.
    Le lock c'est pour gérer l'exclusion mutuelle des threads lors de l'accès à une ressource partagée. Rien à voir avec le problème exposé.

    Concernant le problème, on ne peut pas avoir un flux en écriture et en flux en lecture sur le même fichier en même temps. Avant de lire tu dois fermer le flux ouvert en écriture.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    Merci à vous deux pour votre réponse.

    En effet, le lock rien à voir, au contraire , le but serait (pour résumer) :

    J'ecris une partie N du fichier, Puis en meme temps que j'ecris la partie suivant N+1, je relis la partie N (grosso modo hein !)...

    Ce que je ne comprends pas trop du coup, c'est l'interret du parametre (si peu documenté) FileShare, ni à quoi servent les SafeFileHandlers si on ne peut pas avoir 2 flux sur un fichier...

    Cette histoire de flux exclusif est peut etre une lacune .NET ?
    Je me demande comment des softs du style "Download manager" font pour remplir un fichier avec plusieurs buffers en parallele....

  5. #5
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Ce que je ne comprends pas trop du coup, c'est l'intérêt du paramètre (si peu documenté) FileShare, ni à quoi servent les SafeFileHandlers si on ne peut pas avoir 2 flux sur un fichier...
    FileShare.Read indique que tu autorises d'autres flux à lire le fichier (plusieurs flux en lecture sur le même fichier). On peut l'empêcher avec FileShare.None par exemple. Donc le paramètre a son intérêt.

    Pour ce qui est de la classe SafeFileHandle, elle permet d'avoir un lien sur un handle de fichier, rien à voir avec des accès multiples à un fichier à ma connaissance.

    Néanmoins on peut lire et écrire sur le même fichier, mais il faut pour cela utiliser un seul flux car avec deux c'est interdit.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // Flux en lecture / écriture
    FileStream fs = File.Open(@"c:\test.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None);
    // Flux en écriture sur le flux principal
    StreamWriter sw = new StreamWriter(fs);
    // Flux en lecture sur le flux principal
    StreamReader sr = new StreamReader(fs);
     
    // Je mémorise la position dans le flux
    long position = fs.Position;
    // J'écris sur le flux
    sw.Write("Hello world");
    // Je force l'écriture des données sur le flux
    sw.Flush();
    // Je me repositionne pour pouvoir lire les données écrites
    fs.Position = position;
    // Je lis les données écrites
    string s = sr.ReadToEnd();
    Dure soirée pour ne pas y avoir pensé plus tôt.

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    ok merci c'est tres clair ainsi.

    Malheureusement ca risque de ne pas trop m'arranger vu que je voulais faire les 2 en meme temps (1 thread pour chaque)...

    Je vais faire des essais, il y a forcement une solution, je ne vois pas les SuperCopier, Download Manger et companie n'utiliser qu'un seul flux d'ecriture à la fois...

  7. #7
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Les phases de lecture et d'écriture ne peuvent pas être simultanées, ce qui est logique. Dans le flux on est positionné à un endroit pas à plusieurs.

    Pourquoi veux-tu lire le bloc précédent pendant que tu écris le suivant ? Est-ce nécessaire ?
    Ne peux-tu pas attendre la fin de la lecture pour écrire le bloc suivant ?

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    C'est pour le boulot, je passe mon temps à copier des fichiers de plusieurs GO vers un NAS (via disque reseau ou FTP), et il arrive que les fichiers arrivent corrompus à destination.

    Oui biensur je peux Ecrire puis lire, mais j'esperais pouvoir faire les "2 en meme temps" pour un gain de temps plus que considerable !!!

  9. #9
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    Salut,
    je pense que la meilleure solution niveau robustesse/intégrité des fichiers que tu copies est de partir du principe que lorsque la copie a commencé, toutes les modifs en écriture ne seront appliquées qu'au fichier source. Le fichier destination sera l'image du fichier source tel qu'il était au lancement de la copie.
    En fait le mieux je pense serait de soit interdire l'accès en écriture entre le lancement de la copie et la fin de la copie, soit d'écrire dans une seconde version du fichier, qui remplacera le fichier d'origine à la fin de la copie (quand le vrai fichier original sera à nouveau disponible).

  10. #10
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    Merci pour ta réponse, mais tu n'as visiblement pas bien compris mon objectif final :

    un outil pour copier des fichiers, qui garantisse que le fichier destination soit identique à la source grace à un checksum sur les 2 fichiers, sans pour autant rendre la copie du fichier 2 fois plus longue...

    Je cherche donc à pouvoir lire une partie du fichier destination en meme temps que j'ecrive sur une autre partie de ce meme fichier.

  11. #11
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    C'est pour le boulot, je passe mon temps à copier des fichiers de plusieurs GO vers un NAS (via disque reseau ou FTP), et il arrive que les fichiers arrivent corrompus à destination.
    C'est avec une copie via Windows que tu as ce problème ? (ce qui revient à faire un File.Copy en .Net)

    Je cherche donc à pouvoir lire une partie du fichier destination en mime temps que j'écrive sur une autre partie de ce même fichier.
    C'est impossible. Soit tu lis, soit tu écris. Mais pas le deux en même temps.

    La seule solution pour moi, à part le File.Copy, c'est de lire un bloc du fichier source, de l'écrire dans le fichier destination et de le relire voir si tout est correct. Sinon on recommence l'opération pour ce bloc. Eventuellement allouer à l'avance l'espace disque pour le fichier destination.

    Je ne pense pas qu'on puisse faire beaucoup mieux, mais n'ayant jamais à faire ce type de traitement je ne m'avancerais pas plus que ça ^^

  12. #12
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    C'est avec une copie via Windows que tu as ce problème ?
    tout à fait, mais toujours vers un pc distant dans le domaine, ou via FTP (là j'aurai peut etre un peu plus de facilités vis à vis de mon probleme).

    Je me demande si l'impossibilité dont tu parle est une limitation C# ou Windows tout simplement

    Je suis en train de decortiquer un projet open Source qui semble faire ce que je veux, je vous dirai si je trouve quelque chose d'interressant.

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 92
    Par défaut
    Euh... j'ai peut être pas bien compris ce que tu voulais faire, mais en tout cas, chez moi, ça, ça marche ( c'est à dire que ça compile et s'éxecute sans générer d'exeption ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FileStream m_writer = newFileStream("toto.txt", FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite, 1, true);
    FileStream m_reader = newFileStream("toto.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1, true);
    Le seul truc que j'ai changé, c'est que j'ai mis FileShare.ReadWrite à chaque FileStream.

  14. #14
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    Et dire que c'etait sous mes yeux, je viens de faire l'essai, et :

    1) non seulement avec ces parametres j'arrive à lire et ecrire "en meme temps" avec 2 flux differents (ce qui parait logique avec le parametre FileShare.ReadWrite)

    2) mais en plus, les autres applis ne peuvent pas ouvrir le fichier durant l'operation, la par contre je ne comprend pas trop pourquoi vu que FileShare.ReadWrite.

    Bref contre toute attente, j'obtiens le resultat souhaité, merci Idrakis

    Si quelqu'un à l'explication du point 2, je suis prenneur.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/02/2006, 14h49
  2. Réponses: 1
    Dernier message: 27/10/2005, 10h15
  3. [Système] Comment copier un fichier dans le presse papier ?
    Par le y@m's dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 19/09/2005, 12h03
  4. Réponses: 4
    Dernier message: 17/06/2005, 10h09
  5. Comment décompresser un fichier dans une application ?
    Par f6dqm1 dans le forum Composants VCL
    Réponses: 8
    Dernier message: 14/01/2005, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo