2009-03-26 7 views
15

Desidero aprire un file per la lettura in modalità esclusiva e, se il file è già stato aperto da qualche processo/thread, desidero ricevere un'eccezione. Ho provato il seguente codice, ma non funzionante, anche se ho aperto il file foo.txt, posso ancora raggiungere l'istruzione Console.WriteLine. Qualche idea?apre il file in modalità esclusiva in C#

static void Main(string[] args) 
{ 
    using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open, 
    FileAccess.Read, FileShare.None)) 
    { 
     Console.WriteLine ("I am here"); 
    } 

    return; 
} 
+0

"anche se ho aperto il file foo.txt" -> come l'hai aperto? –

+0

Sì, Mehrdad. L'ho aperto, quindi eseguo il mio programma, ancora posso leggere la dichiarazione di Console.WriteLine. Qualche idea? – George2

+0

Con il blocco note? Blocco note non blocca il file durante l'esecuzione. Legge il file in memoria e lo riapre per scrivere quando si salva. –

risposta

1

Io suggerirei di usare il membro FileAccess.ReadWrite perché alcuni file potrebbero essere già aperto, ma è consentire l'accesso Read sul file. Tuttavia, suppongo che in condizioni non eccezionali, tutti i file aperti per l'accesso a Read/Write non consentano il tuo codice a Write nel file.

Naturalmente (come già spiegato da Mehrdad), se si utilizza un editor come Blocco note per aprire il file come test, non sarà possibile limitare l'accesso perché Blocco note non blocca affatto il file.

+0

Grazie Cerebrus, hai ragione e sto usando il blocco note per aprirlo ed eseguire il mio programma per testarlo. Qualche idea per verificare se un file è aperto o meno (ad esempio, voglio che il mio codice sia in grado di verificare se il blocco note lo ha aperto)? – George2

+0

No, non penso che ci sia ... eccetto che catturando IOException nel codice che tenta di leggere successivamente il file. – Cerebrus

+0

La mia situazione è, un thread è serializzazione (utilizzando serializzazione XML) al file, un altro thread del lettore viene letto da questo file. Non voglio che il thread del lettore funzioni su questo file mentre è in corso la serializzazione XML, qualche idea? – George2

16

Quello che stai facendo è la cosa giusta. Probabilmente lo stai solo provando in modo errato. Dovresti aprirlo con un programma che blocchi il file quando è aperto. Blocco note non funzionerebbe. È possibile eseguire l'applicazione due volte per vedere:

static void Main(string[] args) 
{ 
    // Make sure test.txt exists before running. Run this app twice to see. 
    File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None); 
    Console.ReadKey(); 
} 
+0

Grazie Mehrdad, comunque, per verificare se un file è già stato aperto da un altro thread/processo? – George2

+0

Non penso che ci sia un modo per scoprire se un processo ha aperto un file e ci sta lavorando. Tecnicamente, il file non è più aperto dopo che il blocco note lo carica in memoria. Penso che questo sia il modo giusto per farlo come blocco note o altri programmi non possono aprirlo di nuovo (per leggere o salvare) che va bene, penso. –

+0

Grazie Mehrdad, ho provato che hai ragione. la mia situazione è, un thread è serializzazione (utilizzando serializzazione XML) al file, un altro thread del lettore viene letto da questo file. Non voglio che il thread del lettore funzioni su questo file mentre è in corso la serializzazione XML, qualche idea? – George2

2

FileShare.NONE funziona solo se un altro processo ha anche aperto il file senza permettendo così di essere condivise per legge.

Programmi come Blocco note e Visual Studio non bloccano i file di testo.

+0

Grazie Jakob, comunque, per verificare se un file è già stato aperto da un altro thread/processo? – George2

+0

Ciao Jakob, la mia situazione è, un thread è la serializzazione (usando la serializzazione XML) nel file, un altro thread del lettore viene letto da questo file. Non voglio che il thread del lettore funzioni su questo file mentre è in corso la serializzazione XML, qualche idea? – George2

+0

Come stai serializzando? Durante la serializzazione è necessario aprire il file esclusivamente (ad esempio FileAccess.Write e FileShare.None). –

3

Quello che hai fatto è corretto.

Se avete bisogno di quali sono tutti i file già aperti, quindi non v'è un modo per vedere da NtQuerySystemInformation

Si può ottenere un'idea da http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

che ottiene tutti i file aperti in una directory che può .. essere esteso a un singolo file sia aperto o no ...

+0

Grazie lakshmanaraj, la mia situazione è, un thread è serializzazione (utilizzando serializzazione XML) al file, un altro thread del lettore viene letto da questo file. Non voglio che il thread del lettore funzioni su questo file mentre è in corso la serializzazione XML, qualche idea? – George2

+0

È possibile bloccare il file o eseguire un mutex impostando un semaforo sull'operazione. Il nome del file – lakshmanaraj

+0

è arbitrario, quindi è difficile da bloccare. Maggiori dettagli, copio file arbitrari dalla macchina remota alla macchina locale usando il thread del writer e un thread del lettore eseguirà la scansione della cartella e leggerà le informazioni per i nuovi file in arrivo – George2

2

prova scrivendo un programma in modalità semplice console che si apre il file e quindi attende:

static void Main(string args[]) 
{ 
    using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
     Console.Write("File is open. Press Enter when done."); 
     Console.ReadLine(); 
    } 
} 

Eseguire il programma dalla riga di comando (o un'altra istanza di Visual Studio), quindi eseguire il programma. In questo modo, puoi giocare con valori diversi per FileMode e FileShare per assicurarti che il tuo programma reagisca correttamente in tutti i casi.

E, no, non è necessario verificare se il file è aperto per primo. Il tuo codice dovrebbe generare un'eccezione se il file è già aperto. Quindi tutto ciò che devi fare è gestire quell'eccezione.

+0

Ciao Jim, la mia situazione è, un thread sta copiando il file (usando il metodo File.Move), e un altro thread viene letto dal file. Non voglio che il thread del lettore legga una parte del file mentre la copia è in corso (è per questo che voglio avere la modalità aperta esclusiva), il mio codice pubblicato risolve questo problema? – George2

+0

Sì, il tuo codice risolve il problema. Non aprirà il file se File.Move è nel mezzo di copiarlo. –

+0

Jim, come faccio a sapere se qualche programma (!) Lo apre? O blocco note o qualcos'altro. O come faccio a sapere se viene copiato in questo momento? –