2009-03-16 9 views
7

È possibile aprire un file in un modo che consenta la successiva cancellazione/rinomina della sua cartella principale?Aprire il file senza (davvero) bloccarlo?

So che si può fare questo:

File.Open("foo.bar", FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete) 

che consentirà il file da cancellare quando la maniglia file viene chiuso. Tuttavia, se non consente la cancellazione della cartella principale senza errori.

Non ho trovato nulla nel framework. Ho trascurato qualcosa, o c'è una API nativa a cui posso intervenire.

Nota: non mi interessa se ottengo un'eccezione quando si utilizza lo stream del file eliminato. In effetti sarebbe l'ideale.

UPDATE:

Così l'idea più promettente è stato il Hardlink, ma non riesco proprio a farlo funzionare. Ricordo ancora Access Denied quando provo a eliminare la directory principale. Ecco il mio codice:

class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); 

    static void Main(string[] args) 
    { 
     string hardLinkPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
     string realPath = @"C:\foo\bar.txt"; 
     if (CreateHardLink(hardLinkPath, realPath, IntPtr.Zero)) 
     { 
      using (FileStream stream = File.Open(hardLinkPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) 
      { 
       Console.Write("File locked"); 
       Console.ReadLine(); 
      } 

      File.Delete(hardLinkPath); 
     } 
     else 
      Console.WriteLine("LastError:{0}", Marshal.GetLastWin32Error()); 
    } 
} 

risposta

0

La soluzione migliore che riesco a trovare è copiare il file in una posizione temporanea. Quindi, apri il file temporaneo e cancellalo quando ho finito.

+0

Suona come qualcosa che farei. Forse puoi copiare in memoria se il file è abbastanza piccolo? – strager

+0

sì, lo stiamo facendo ora, ma ci sono molti file, e sono abbastanza grandi da 3Mb a 100Mb. Provoca un sacco di problemi con il GC. –

0

FileOpen utilizza CreateFile in Kernel32.dll. Non sono sicuro che sarete in grado di ottenere qualcosa di più di quanto il framework .NET vi fornisca, poiché tutte le opzioni sono già presenti, a meno che non lo eseguiate come transaction.

+0

Sto pescando attraverso la documentazione ora. Sai se un file aperto con CreateFileTransacted, consente l'eliminazione della cartella principale o lo stai suggerendo come un'opzione? –

+0

Presumo che ci siano 2 thread attivi sul file, uno da aprire e un altro che tenta di eliminare contemporaneamente? –

+0

Beh alla fine, ma ne controllo solo uno. –

1

Se si sta lavorando con un NTFS è possibile creare un altro hardlink sul file in una posizione temporanea, si eviterà il sovraccarico della copia del file e il primo link dovrebbe ancora essere cancellato (il file stesso o un contenitore contenente directory) senza effettuare il secondo.

+0

Hmmm, questo mi è sembrato molto promettente, tuttavia ottengo ancora l'errore quando ho eliminato la cartella principale. Forse sto facendo qualcosa di sbagliato. Hai provato tu stesso? –

+0

Gli hard link devono essere identici al file originale, cioè non esiste un vero e proprio concetto di puntatore "principale" sul file, funzionano tutti in modo identico. (Aggiunge un altro puntatore di directory) Non li ho usati personalmente in questa esatta situazione, ma dovrebbe funzionare ... – Eric

+0

Vedere il codice che ho aggiunto, questo non sembra essere il caso. –

Problemi correlati