2
votes

Utilisation de C # pour vérifier si un fichier est en cours d'utilisation

J'ai vu ces deux questions:

Vérifier si le fichier est en cours d'utilisation

Existe-t-il un moyen de vérifier si un fichier est en cours d'utilisation?

Aucun d'eux ne m'a fourni toutes les informations dont j'avais besoin, et j'avais besoin de plus de précisions sur certaines réponses , mais les questions datent de plusieurs années, donc je ne savais pas si je devais essayer d'obtenir des réponses à partir de là à ce stade.

J'ai donc posté une nouvelle question. Quelque chose comme

public string myFile;
myFile = @"C:\somepath\somefile.pdf";

if (myFile isinuseorwhatever)
{
     MessageBox.Show("File is in use!! Close it and try again");
     return;
}
else
{
     MessageBox.Show("That worked. Good job!")
     //Do Stuff and lots of lines of stuff.
}

Je peux le faire en utilisant la gestion des exceptions, mais le problème est que je dois faire la vérification avant d'exécuter les nombreuses lignes de code.

J'ai le sentiment que je dois créer une classe pour la vérifier, puis exécuter cette classe. Pour être honnête, je suis assez nouveau dans le codage, donc je ne suis pas sûr à 100% du fonctionnement des classes.

Je sais comment utiliser try et catch code>, mais cela ne fonctionnera pas ici car l'exception se produit dans les dernières lignes de code du bloc try , donc tout cela se produira avant qu'il n'atteigne l'exception. Comme, ce programme copie un fichier, le renomme, le déplace dans un répertoire différent, puis supprime l'original, ce qui est la dernière chose qu'il fait. Si un utilisateur a ouvert le fichier, il fera tout cela mais lèvera une exception lorsqu'il essaiera de le supprimer. J'en ai besoin pour lancer l'exception AVANT qu'il ne copie, renomme, déplace et ainsi de suite.


1 commentaires

Vous vous battez trop fort. Vous devez essayer de renommer le fichier. Attrapez toute exception, ce qui signifie que le fichier est probablement en cours d'utilisation. Si aucune exception, déplacez le fichier (déplacer signifie qu'il n'y a pas d'original à supprimer, car il a été déplacé - vous ne devez supprimer que si vous copiez). Le faire dans cet ordre signifie que l'une des solutions des publications que vous avez liées fonctionnera pour vous.


3 Réponses :


4
votes

Vous pouvez verrouiller un fichier pour un accès exclusif en utilisant FileStream avec FileShare.None . Donc si nous voulons implémenter les premières requêtes mentionnées c'est-à-dire

  1. vérifier si le fichier est en cours d'utilisation, si oui, informer l'utilisateur
  2. sinon verrouillez-le, donc personne ne l'ouvrira
  3. copier le fichier
  4. renommer le fichier

Vous pouvez implémenter le code suivant:

try
{
    using (Stream stream = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
    {
        // Here you can copy your file
        // then rename the copied file
        using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
        {
            writer.Write(""); // truncate the file, making it unusable to others
        }
    }
    while (true)
    {
        try
        {
            File.Delete("1.docx");
        }
        catch 
        {
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}

Je pense que vous savez comment copier et renommer le fichier (sinon le commenter et j'ajouterai le code ici). La deuxième partie de votre question est un peu délicate. Parce que vous ne pouvez pas utiliser Filestream pour supprimer un fichier. Dès que vous disposez du filestream pour appeler File.Delete ("YourFile.doc") , il est possible que certains y accèdent exactement à ce moment. Je vous recommande de tronquer le fichier lorsqu'il est verrouillé, afin qu'il soit inutilisable pour les autres utilisateurs. Vous pouvez également garder votre processus en boucle jusqu'à ce que le fichier soit publié. Le code ressemblerait à ceci:

try
{

    using (Stream stream = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
    {
        // Here you can copy your file
        // then rename the copied file
    }
}
catch (Exception ex)
{
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}


0 commentaires

0
votes

Utilisez une valeur booléenne et définissez-la sur false si une exception est levée lors de la tentative d'ouverture du fichier.

Exemple:

    string path = "Your Path";
    bool available = true;
    try
    {
        using (FileStream fs = File.Open(path, FileMode.Open))
        {

        }
    }
    catch(Exception ex)
    {
        available = false;
    }


1 commentaires

Cela ne fonctionnera pas. Une fois que vous fermez le fichier, un autre processus peut verrouiller, supprimer, renommer ou rendre le fichier indisponible. Au moment où vous dépassez le bloc catch , il n'y a aucune garantie que la valeur de available vous indique quel est le statut réel du fichier.



1
votes

La réponse acceptée actuelle de @ code-pope inclut dans un try-catch trop de code, elle considère que chaque exception s'est produite comme "le fichier est en cours d'utilisation", alors qu'en réalité une exception peut également apparaître pour d'autres raisons

Je le ferais quelque chose comme ceci:

string path = "some path";
FileStream fs = null; 
try
{
    fs = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch(Exception ex)
{
    //ops, cannot open file, better not keep on
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}

// lets go on now...
using (fs)
{
    // do your work
}


1 commentaires

Dans votre code, l'action de suppression n'est pas implémentée. Il a également demandé la suppression du fichier. Si vous souhaitez supprimer le fichier, vous avez besoin d'un autre essai, catch.