Omezení přístupu k souboru   zodpovězená otázka

C#, I/O operace, .NET

dobrý den,

potřeboval bych realizovat omezování přístupu k souboru (v rámci aplikace) pokud je momentálně v aplikaci, v některém z formulářů soubor používán. V podstatě by mělo být chování stejné jako je u Ecelu. Pokud je v jedné instanci excelu soubor otevřen, v další je již pouze Ke čtení.

Patrně by bylo vhodné použít FileSecurity, nicméně mi není zcela jasná detailní aplikace.

Mělo by to fungovat tak, že konkrétní formulář nastaví po otevření souboru jeho práva pouze pro čtení (pro ostatní formy, resp. instance) a pak je po ukončení používání opět nazpátek vrátí do původního stavu. Potřebuji, aby ostatní instance formů mohly z tohoto souboru pouze číst.

Potřeboval bych maličko nasměrovat.

Předem děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dá se to realizovat velmi jednoduše pomocí specifikování přístupu ostatních FileStreamů (procesů) k otevřenému souboru. Asi by bylo nejlepší vytvořit si nějakou třídu pro I/O operace v rámci projektu (singleton?) a v ní po nutnou dobu udržovat otevřený FileStream.

Syntaxe:

public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share)

share určuje, jakým způsobem bude otevřený soubor sdílen ostatními FileStreamy (procesy).

Hodnota/Ostatní procesy můžou:

System.IO.FileShare.Delete/Mazat

System.IO.FileShare.None/Nic

System.IO.FileShare.Read/Číst

System.IO.FileShare.ReadWrite/Číst a zapisovat

System.IO.FileShare.Write/Zapisovat

/* Otevře (nebo vytvoří) soubor pro zápis, ostatní procesy
(FileStreamy) mají k tomuto souboru přístup pouze pro čtení */
FileStream fs = new FileStream(@"C:\Data.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji za vaši odpověď, nicméně nevím jestli toto řešení je vhodné. Možná jsem jen nepochopil správnou implementaci tohoto řešení.

Jednotlivé formy totiž mohou přistupovat k předem neznámému počtu různých souborů (jednoho typu) a já potřebuji ošetřit situaci kdy dvě různé instance formu budou přistupovat ke stejnému souboru. Potom ten první má mít věškerá práva a všichni ostatní pouze Read.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To je ale přesně ono - soubor otevřete před konstrukci, kterou Vám popsal pan Linhart, a on se "zamkne". První, kdo ho otevřel, bude mít k souboru všechna práva (musí ho mít po celou dobu otevřený ovšem), pokud ho bude chtít otevřít někdo jiný, díky specifikaci FileShare.Read u toho prvního otevření teď k němu dostane jen práva pro čtení.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokud použiji tuto konstrukci:

FileStream fs = new FileStream(@"C:\Data.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);

nelze již další FileStream otevřít. Pouze když bude nastaveno FileShare.ReadWrite.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To je jasné, máte nastaven FileAccess.Write, což znamená, že stream otevíráte pro čtení.

Musíte udělat Try..Catch blok a zkusit otevřít stream pro zápis (to se povede jen jednou) a pokud to sekže, otevřít ho pro čtení a v aplikaci si poznamenat, že je soubor jen pro čtení.

Jinak pokud ze streamu chcete číst i psát, tak musíte dát FileAccess.ReadWrite v prvním případě.

Raději vysvětlím parametry:

FileMode.OpenOrCreate ... pokud neexistuje, vytvořit, pokud existuje, otevřít

FileAccess.Read/Write/ReadWrite ... oprávnění, která požadujete

FileShare.Read/Write/ReadWrite ... co povolíte ostatním, kteří budou chtít se souborem pracovat, zatímco jej máte otevřený

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Přesně tak jak píšete jsem udělal:

try
            {
                fs = new FileStream(fileName, FileMode.OpenOrCreate,
                    FileAccess.ReadWrite, FileShare.Read);
            }
            catch
            {
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            }

ale pokud při prvním otevření FS použiji FileShare.Read v druhém se mi již nedaří přístup ani jen pro čtení.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Máte pravdu, nefunguje to a to je skutečně záhada, protože podle MSDN by to mělo fungovat přesně tak jak bylo popsáno výše. Samotného mě tento problém zajímá, takže se podívám co s tím...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To mě právě zmátlo a hledal jsem chybu nejdříve u sebe.

Každopádně děkuji za cenné rady.

Jinak tento problém určitě musím brzy vyřešit, takže se pokusím pátrat též, nebo hledat nějaké řešení či jiný způsob jak na to.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já myslím, že to bude omezení filesystému - když jeden zapisuje, ostatní prostě nemůžou ani číst. To je jediné vysvětlení, které mě napadá.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ale když se použije FileShare.ReadWrite tak to vícenásobné otevření FileStreamu funguje. Řekl bych, že je to nějaký bug právě v kombinaci s použitím FileShare.Read.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zajímavé. Možné to je.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Takže řešení je nakonec totálně jednoduché. Chyby byla pouze v použití:

try
{
     fs = new FileStream(fileName, FileMode.OpenOrCreate,
                    FileAccess.ReadWrite, FileShare.Read);
}
catch
{
     fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}

u druhého pokusu přístup je třeba opět použít FileShare ale jako FileShare.ReadWrite.

Děkuji všem za pomoc

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback