Domanda

Ho cercato di bloccare un file in modo che gli altri servizi clonati non possono accedere al file. Ho poi letto il file, e quindi spostare il file una volta terminato. In movimento è consentito utilizzando FileShare.Delete.

Tuttavia nei test dopo, abbiamo scoperto che questo approccio non funziona se siamo di fronte a una condivisione di rete. Apprezzo il mio approccio non può essere stato il migliore, ma la mia domanda specifica è:

Perché il seguito demo lavoro contro il file locale, ma non contro il file di rete?

La specifica più potete essere il migliore, come ho trovato pochissime informazioni nelle mie ricerche, che indica le condivisioni di rete si comportano in modo diverso a dischi locali.

string sourceFile = @"C:\TestFile.txt";
string localPath = @"C:\MyLocalFolder\TestFile.txt";
string networkPath = @"\\MyMachine\MyNetworkFolder\TestFile.txt";

File.WriteAllText(sourceFile, "Test data");

if (!File.Exists(localPath))
    File.Copy(sourceFile, localPath);

foreach (string path in new string[] { localPath, networkPath })
{
    using (FileStream fsLock = File.Open(path, FileMode.Open, FileAccess.ReadWrite, (FileShare.Read | FileShare.Delete)))
    {
        string target = path + ".out";
        File.Move(path, target); //This is the point of failure, when working with networkPath

        if (File.Exists(target))
            File.Delete(target);
    }

    if (!File.Exists(path))
        File.Copy(sourceFile, path);
}

EDIT: vale la pena di ricordare che, se si desidera spostare il file da una condivisione di rete, ad un'altra parte della rete, mentre il blocco è a posto, questo funziona. Il problema sembra solo verificarsi quando si sposta un file all'interno di lo stesso condivisione di file mentre è bloccato.

È stato utile?

Soluzione

Credo mappe System.IO.File.Open () per la funzione API Win32 CreateFile (). Nella documentazione di Microsoft per questa funzione [ http: // msdn .microsoft.com / en-us / library / aa363858 (v = vs.85) aspx ], si cita il seguente:

  

Windows Server 2003 e Windows XP / 2000: si verifica una violazione di condivisione, se viene effettuato un tentativo di aprire un file o una directory per l'eliminazione in un computer remoto quando il valore del parametro dwDesiredAccess è la bandiera di accesso DELETE (0x00010000) OR' eD con qualsiasi altra bandiera di accesso e il file remoto o la directory non è stato aperto con FILE_SHARE_DELETE. Per evitare la violazione di condivisione in questo scenario, aprire il file o la directory remota con l'accesso DELETE solo a destra, oppure chiamare DeleteFile senza prima apertura il file o la directory per l'eliminazione.

In base a questo, si dovrà passare DELETE come parametro FileAccess a IO.File.Open (). Purtroppo, l'enumerazione DELETE non è stata inclusa come opzione.

Questo problema riguarda solo Windows 2003 e precedenti. Ho testato il codice su Windows 2008 R2 SP1, e funziona benissimo. Quindi è possibile che sarebbe anche il lavoro su Windows 2008 pure.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top