Question

J'ai des fichiers .csv que j'utilise dans le cadre d'un banc d'essai. Je peux les ouvrir et les lire sans problème à moins que J'ai déjà le fichier ouvert dans Excel auquel cas je reçois un IOException:

  

System.IO.IOException: Le processus ne peut pas accéder au fichier « TestData.csv » parce qu'il est utilisé par un autre processus

.

Ceci est un extrait du banc d'essai:

using (CsvReader csv = new CsvReader(new StreamReader(new FileStream(fullFilePath, FileMode.Open, FileAccess.Read)), false))
{
    // Process the file
}

Est-ce une limitation de StreamReader? Je peux ouvrir le fichier dans d'autres applications (Notepad ++ par exemple) ne peut donc pas être un problème d'O / S. Peut-être que je dois utiliser une autre classe? Si quelqu'un sait comment je peux contourner ce (à part la fermeture Excel!) Je serais très reconnaissant.

Était-ce utile?

La solution

Comme le dit Jared, Vous ne pouvez pas le faire si l'autre entité qui a ouvert le fichier partagé permet lit. Excel permet partagé lit, même pour les fichiers qu'il a ouvert pour l'écriture. Par conséquent, vous devez ouvrir le filestream avec le paramètre FileShare.ReadWrite .

Le param fileshare est souvent mal compris. Il indique que autres ouvreurs du fichier peut faire. Il applique passé ainsi que ouvre l'avenir. Pensez à FileShare non comme une interdiction rétroactive sur ouvreurs avant (par exemple Excel), mais une contrainte qui ne doit pas être violé avec le courant ouvert ou tout futur apparaît.

Dans le cas de la tentative actuelle d'ouvrir un fichier, FileShare.Read dit « ouvrir ce fichier pour moi avec succès que si elle ouvre des avant ont ouvert il uniquement pour lire. » Si vous spécifiez FileShare.Read sur un fichier ouvert pour l'écriture par Excel, votre open échouera, car il serait contraire à la contrainte, car Excel a ouvert pour écrire .

Parce que Excel a ouvert le fichier pour l'écriture, vous devez ouvrir le fichier avec FileShare.ReadWrite si vous voulez votre ouvert à réussir. Une autre façon de penser à la FileShare param: il indique « l'accès aux fichiers de l'autre gars ».

Supposons maintenant un scénario différent, dans lequel vous ouvrez un fichier qui est pas ouvert par une autre application. FileShare.Read dit « ouvre l'avenir peut ouvrir le fichier avec un accès en lecture seule ».

Logiquement, cette sémantique du sens - signifie FileShare.Read, vous ne voulez pas lire le fichier si l'autre gars est déjà en train d'écrire, et vous ne voulez pas l'autre gars pour écrire le fichier si vous êtes déjà En le lisant. FileShare.ReadWrite signifie, vous êtes prêt à lire le fichier même si l'autre gars est en train d'écrire, et vous avez pas de problème de laisser un autre ouvreur écrire le fichier pendant que vous lisez.

En aucun cas ce permis plusieurs auteurs. FileShare est similaire à une base de données IsolationLevel. Votre réglage souhaité dépend ici de la « cohérence » vous garantit besoin.

Exemple:

using (Stream s = new FileStream(fullFilePath, 
                                 FileMode.Open,
                                 FileAccess.Read,
                                 FileShare.ReadWrite))
{
  ...
}

ou

using (Stream s = System.IO.File.Open(fullFilePath, 
                                      FileMode.Open, 
                                      FileAccess.Read, 
                                      FileShare.ReadWrite))
{
}

Addendum:

Le sur System.IO.FileShare est un peu mince. Si vous voulez vérifier les faits, allez la documentation la fonction CreateFile Win32 , ce qui explique mieux le concept FileShare.

Autres conseils

EDIT

Je ne suis toujours pas 100% sûr pourquoi cela est la réponse, mais vous pouvez résoudre ce problème en passant FileShare.ReadWrite au constructeur FileStream.

using (CsvReader csv = new CsvReader(new StreamReader(new FileStream(fullFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)), false)
{
  ...
}

Ma curiosité a une prise de moi en ce moment et je suis en train de comprendre pourquoi il est la réponse particulière. Si je le découvrir plus tard, je mettrai à jour ce avec les informations.

La meilleure documentation semble effectivement être dans la fonction CreateFile . Ceci est la fonction .Net appellera sous le capot afin d'ouvrir un fichier (créer le fichier est un peu un abus de langage). Il a une meilleure documentation de la façon dont l'aspect de partage de l'ouverture d'un fichier fonctionne. Une autre option est de simplement lire la réponse de Cheeso

Si un autre processus a un fichier ouvert, vous pouvez souvent utiliser File.Copy puis ouvrez la copie. Pas une solution élégante mais pragmatique.

Un autre problème est que si vous ouvrez un FileStream avec FileShare.ReadWrite, après ouvre de ce fichier doit également préciser FileShare.ReadWrite, ou vous obtiendrez le « Un autre processus utilise ce fichier » erreur.

En utilisant les System.Diagnostics;

Vous pouvez simplement appeler Process.Start ( « nom de fichier et chemin »)

Je ne sais pas si cela aide, mais c'est ce que je viens utilisé pour mettre en œuvre un bouton Aperçu PDF sur notre intranet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top