Jak sprawdzić, czy plik jest otwarty?

Odpowiedz Nowy wątek
2003-08-25 10:06

Rejestracja: 17 lat temu

Ostatnio: 12 lat temu

0

Jak sprawdzić, czy plik jest otwarty?

Pozostało 580 znaków

2003-08-25 10:17

Rejestracja: 17 lat temu

Ostatnio: 6 lat temu

0
AssignFile(plik, 'ścieżka_do_sprawdzanego_pliku');
try
    CloseFile(plik);
    ShowMessage('Plik był otwarty.');
except
    ShowMessage('Plik nie był otwarty.');
end;

Słowa kierownika : To, jak wy zdążycie to napisać, to ja mam w szeroko rozumianej du*ie.
http://project1.pl

Pozostało 580 znaków

2014-06-09 22:57

Rejestracja: 6 lat temu

Ostatnio: 5 lat temu

0

Chciałbym odświeżyć nieco powyższy temat. Mam pytanie dotyczące obsługi plików poprze TFileStream. Jak sprawdzić czy dany plik,wybrany do wczytania oraz wykonania dalszych operacji np. edycja itp, jest już otwarty przez inną aplikację?
Robert

edytowany 2x, ostatnio: roboskobo, 2014-06-09 23:04
Nieco odświeżyć? "Nieco" to by było 10 lat temu. I co w ogóle ma Twoje pytanie do tego wątku? :| - Patryk27 2014-06-09 23:04
Dobry odkop nie jest zly. :P - n0name_l 2014-06-09 23:14

Pozostało 580 znaków

2014-06-09 23:08

Rejestracja: 6 lat temu

Ostatnio: 5 lat temu

0

To, że też dotyczy dostępu do plików i sprawdzania czy inna aplikacja nie korzysta z pliku.

Jak kilkaset innych wątków na tym forum :||| - Patryk27 2014-06-09 23:09
Korzystam z tego forum dopiero od kilku miesięcy, ale w tej sprawie nie udało mi się znaleźć niczego bardziej pasującego. - roboskobo 2014-06-09 23:15
I ani przez chwilę nie pomyślałeś o założeniu własnego wątku? - Patryk27 2014-06-09 23:17
Oczywiście, że pomyślałem. Czyli mam rozumieć, że to jest Twoja podpowiedź na mój problem - założenie nowego wątku ? OK. Nie ma problemu. - roboskobo 2014-06-09 23:28

Pozostało 580 znaków

2014-06-09 23:24
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 miesiąc temu

Lokalizacja: Szczecin

0

To czy plik jest w użyciu przez inny program, co utrudnia dostęp do niego poprzez zapis sprawdzisz tak jak pokazano w kodzie WinAPI, w wątku pod poniższym adresem: http://stackoverflow.com/ques[...]ecking-file-is-open-in-delphi o ile o to Ci chodzi.

Można też sprawdzić czy zmieniła się na przykład zawartość katalogu poprzez funkcję API ReadDirectoryChangesW. Opisano to pokrótce z przykładem pod następującym adresem http://stackoverflow.com/ques[...]directorychangesw-omit-events


Pozostało 580 znaków

2014-06-09 23:50

Rejestracja: 6 lat temu

Ostatnio: 5 lat temu

0

Niestety to nie to.
Mój kod obecnie wygląda tak:

var
  fs_plik: TFileStream;
  s_nazwa: string;
  E: Exception;
begin
    fs_plik := nil;
  try
    try
    if not opnDialog.Execute then Exit;
      memPlikTekst.Lines.LoadFromFile(opnDialog.Filename);
      fs_plik:= TFileStream.Create(opnDialog.FileName, fmOpenRead or fmShareDenyNone);
      memPlikTekst.Lines.LoadFromStream(fs_plik);
      edtSciezkaPliku.Text:= opnDialog.FileName;
      s_NazwaPliku:= opnDialog.FileName;
     except
      on E: Exception do
        ShowMessage('Błąd = ' + E.Message);
    end;
  finally
    if Assigned(fs_plik) then FreeAndNil(fs_plik);

Chciałbym gdzieś w mój kod wpisać polecenia, które sprawdzą, że wybrany plik jest / lub nie jest używany przez inny program.

dodanie znacznika <code class="delphi"> - furious programming

edytowany 1x, ostatnio: furious programming, 2014-06-10 02:20
s_NazwaPliku jest zmienną globalną w Unicie - roboskobo 2014-06-09 23:51
Wstawiaj kod w znaczniki kolorujące składnię! - furious programming 2014-06-10 02:20

Pozostało 580 znaków

2014-06-09 23:58
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 miesiąc temu

Lokalizacja: Szczecin

0

To przecież kod podany przeze mnie w poprzednim postcie w pierwszym linku dokładnie to robi. Chodzi o to co wkleił tam użytkownik o nazwie JosephStyons. Jeżeli nie tego oczekujesz, to ja nic więcej raczej nie dodam.


edytowany 1x, ostatnio: furious programming, 2014-06-10 02:20

Pozostało 580 znaków

2014-06-10 00:18

Rejestracja: 6 lat temu

Ostatnio: 5 lat temu

0

Z jedną małą różnicą - przykład operuje zmienną typu HFile, a u mnie jest TFileStream

edytowany 1x, ostatnio: roboskobo, 2014-06-10 00:56

Pozostało 580 znaków

2014-06-10 00:58
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 miesiąc temu

Lokalizacja: Szczecin

1

Wiesz, jestem wprawdzie po paru piwach, ale tolerancje na ulubione alko po grillowanym jedzonku mam ok. I ja w kodzie osobnika jakiego nick podałem, widzę czyste WinAPI i tak najlepiej go użyć.

function IsFileInUse(fName: string) : boolean;
var
  HFileRes: HFILE;
begin
  Result := False;
  if not FileExists(fName) then begin
    Exit;
  end;

  HFileRes := CreateFile(PChar(fName)
    ,GENERIC_READ or GENERIC_WRITE
    ,0
    ,nil
    ,OPEN_EXISTING
    ,FILE_ATTRIBUTE_NORMAL
    ,0);

  Result := (HFileRes = INVALID_HANDLE_VALUE);

  if not(Result) then begin
    CloseHandle(HFileRes);
  end;
end;

Sorry, ale pomimo usilnych starań, nie widzę tutaj próby otwierania niczego typu TextFile. Dla pewności można tylko i tak zwolnić uchwyt do pliku. Nawet jeśłi się ten plik uda otworzyć. A dalej już dłubać pod VCL, jeżeli taka Twoja wola.


Dzięki bardzo. Właśnie dłubę poza funkcją. Zaraz będę testował. - roboskobo 2014-06-10 01:16

Pozostało 580 znaków

Opi
2014-06-10 08:24
Opi

Rejestracja: 15 lat temu

Ostatnio: 8 miesięcy temu

2
{Najprostrzy sposób i za razem najlepszy}
function CzyPlikUzywany(Nazwa: string): boolean;
begin
 Result := not RenameFile(Nazwa,Nazwa);
end;

{lub modyfikacja powyższego}
function CzyPlikUzywany(Nazwa: String): Boolean;
var
 hPlik: hFile;
begin
 Result := not RenameFile(Nazwa, Nazwa);

 if not Result then
   begin
    hPlik  := CreateFile(pChar(Nazwa), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);
    Result := hPlik = INVALID_HANDLE_VALUE;
    if not Result then CloseHandle(hPlik);
   end;
end;

{Sposób 3}
function PlikUzywany1(Plik: string): Boolean;
var
 hPlik: TextFile;
begin
 try
  AssignFile(hPlik,Plik);
 except end;

 try
  {$I-}
  Reset(hPlik);
  {$I+}
 except end;

 if IOResult = 32 then Result := True
 else
 if IOResult = 0 then Result := False;

 try
  CloseFile(hPlik);
 except end;
end;

{Sposób 4}
function PlikUzywany2(Nazwa: string): boolean;
var
 Plik: file;
begin
 {$I-}
 Assign(Plik, Nazwa);
 FileMode := 0;
 Reset(Plik);
 Close(Plik);
 {$I+}
 Result := (IOResult = 0) and (Nazwa <> '');
end;
Pokaż pozostałe 2 komentarze
Plik otwarty w Notepad++ można nawet usunąć. - bogdans 2014-06-10 09:20
Być może dlatego że plik nie jest otwarty. Po prostu program otwiera plik odczytuje zawartość i go zamyka (gdy zapisujesz otwiera ponownie). - kAzek 2014-06-10 09:24
Tak samo jest z GomPlayerem. Gdy jakiś plik jest pod nim odtwarzany, to da się go usunąć z pod Total Commandera, ale plik "znika" dopiero gdy odtarzanie się zakończy. - olesio 2014-06-10 16:23
Jeżeli konsolowe polecenie OpenFiles nie oszukuje, to notepad++ rzeczywiście nie trzyma otwartych plików. - bogdans 2014-06-10 16:32
W testowym projekcie otwórzcie sobie jakiś tymczasowy plik funkcją FileOpen i spróbujcie go usunąć w TC (czy normalnie w Eksploratorze Windows) na pewno nie uda się aż do wywołania FileClose lub zakończenia działania aplikacji która plik otworzyła. - kAzek 2014-06-10 16:39

Pozostało 580 znaków

2014-06-12 09:22

Rejestracja: 6 lat temu

Ostatnio: 5 lat temu

0

Dziękuje wszystkim za pomoc. W swoim programie wybrałem sprawdzanie Olesia. Oczywiście działa
Natomiast mam jedną zagwózdkę - po sprawdzeniu czy plik jest używany nie wychodzi z "try" - trzecie w procedurze, zamieniałem finally z tego bloku na except, ale jest jeszcze gorzej - możecie zerknąć co jest nie tak. Może kolejność ?

procedure TMainForm.btnOtworzClick(Sender: TObject);
var
  fs_plik: TFileStream;
  s_nazwa: string;
  E: Exception;
begin
    fs_plik := nil;
  try
    try
    if not opnDialog.Execute then Exit;
      s_nazwa:= opnDialog.FileName;
      try
      if CzyPlikOtwarty(s_nazwa) then
      begin
          ShowMessage('Plik jest uzywany przez inna aplikacje');
          btnWlasciwosci.Enabled:= False;
          exit;
        end;
      finally
//        memPlikTekst.Lines.LoadFromFile(opnDialog.Filename);
        fs_plik:= TFileStream.Create(opnDialog.FileName, fmOpenRead or fmShareDenyNone);
        memPlikTekst.Lines.LoadFromStream(fs_plik);
        edtSciezkaPliku.Text:= opnDialog.FileName;
        s_NazwaPliku:= opnDialog.FileName;
        btnWlasciwosci.Enabled:= True;
      end;
//    else
//          ShowMessage('Plik nie jest uzywany');

//    Alternatywa otwierania pliku
//    if not PromptForFileName
//        (s_nazwa, 'Pliki tekstowe (*.txt)|*.txt|Pliki *.dat|*.dat|Pliki *.csv|*.csv',
//         '', 'Otwórz plik danych', '', False) then Exit;
//      fs_plik:= TFileStream.Create(s_nazwa, fmOpenRead or fmShareDenyNone);
//      s_NazwaPliku := s_nazwa;
    except
      on E: Exception do
        ShowMessage('Błąd = ' + E.Message);
    end;
  finally
    if Assigned(fs_plik) then
      FreeAndNil(fs_plik);
    lblUtworzenie.Caption:= 'Data i czas utworzenia :';
    pnlRozmiarPlik.Caption:= 'Rozmiar pliku :';
    memStrumien.Text:= NullAsStringValue;
  end;
end;

dodanie znacznika <code class="delphi"> - furious programming

edytowany 1x, ostatnio: furious programming, 2014-06-12 15:34
Po raz kolejny przypominam o wstawianiu kodu w znaczniki kolorujące składnię! - furious programming 2014-06-12 15:35

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0