Czy plik jest używany i przez jaki program

0

Jak sprawdzić, czy plik jest używany. Zależy mi na możliwości sprawdzenia dowolnego pliku i aby nie było to coś w stylu:
"usunąć, zmienić nazwę i jak system wyświetli błąd to znaczy że go używa"

Znalazłem taki przykład:

var
  f : file;
  Path : String;
begin
AssignFile (f,'C:\upx.exe');
{$I-} reset (f); {$I+}
 case IOResult of
  0 :  ShowMessage('Plik nie jest używany');
  2 :  ShowMessage('Nie ma wskazanego pliku');
  32 : ShowMessage('Plik jest używany !');
 end;
end;

ALE... to działa TYLKO na pliki EXE, a ja chce dla każdego pliku móc sprawdzić.
Dodatkowo (jeśli to możliwe) przez jaką aplikację plik jest używany ??

Bardzo mi na tym zależy

0

zadeklaruj f jako textfile i Twoj kod bedzie dzialac

0
Passage napisał(a)

zadeklaruj f jako textfile i Twoj kod bedzie dzialac

Super ! Dzięki Passage :)

A tak przy okazji znalazłem także inny przykład. Nie zdążyłem sprawdzić ;)
Może komuś się przyda :)

unit exclusiveio;

interface

  const
    buffersize = 2048;

  type
    texclusiveio =
      class(tobject)
        public
          constructor create;
          function open (const filename:  string):  boolean;
          function close:  boolean;
          function endoffile:  boolean;
          function getline:  string;

        private
          buffer   :  array[1..buffersize] of byte;
          bytesread:  integer;
          fileend  :  boolean;
          fileopen :  boolean;
          exclusive:  file;
          position :  0..buffersize;  {0 signifies invalid data in buffer}

          procedure readblock;
          procedure checkforblockend;

      end;


implementation

  uses
    sysutils;  {fileexists}

  constructor texclusiveio.create;
  begin
    inherited create;
    fileend  := false;
    fileopen := false;
    position := 0;
  end {create};


  procedure texclusiveio.readblock;
  begin
    {do nothing if file is not open}
    if  fileopen
    then begin

      try
        blockread(exclusive, buffer, sizeof(buffer), bytesread);
        if   bytesread = 0
        then begin
          position := 0;
          fileend := true;
          fileopen := false
        end
        else position := 1;
      except
        on einouterror do
        begin
          fileopen := false;
          position := 0;
        end
      end;

    end
  end {readblock};


  function texclusiveio.open (const filename:  string):  boolean;
    var
      savemode:  word;
  begin
    if   fileexists(filename)
    then begin
      try
        savemode := system.filemode;

        {"fmshareexclusive" guarantees that a file that is still open
         for writing will not be read until after it has been closed.
         this only works on typed or untyped files -- not textfiles}
        system.filemode := fmshareexclusive;
        assignfile (exclusive, filename);
        reset (exclusive, 1);   {read 1-byte at a time}
        system.filemode := savemode;
        fileopen := true
      except
        on einouterror do
        begin
          fileopen := false;
          fileend := true
        end
      end;

      {if open was successful, go ahead and read first block}
      if   fileopen
      then readblock;
    end
    else fileopen := false;

    result := fileopen
  end {openfile};


  function texclusiveio.close:  boolean;
  begin
    try
      closefile(exclusive);
      fileopen := false;
      result := true;
    except
      on einouterror do result := false
    end
  end {closefile};


  function texclusiveio.endoffile:  boolean;
  begin
    result := fileend  or  (not fileopen)
  end {endoffile};


  procedure texclusiveio.checkforblockend;
  begin
    if   position = bytesread
    then
      if   eof(exclusive)
      then begin
        fileend := true;
        position := 0;
      end
      else readblock
    else inc(position)
  end {checkforblockend};


  function texclusiveio.getline:  string;
  begin
    result := '';
    if   fileopen and (position <> 0)
    then begin

      {accept characters from buffer until lf or cr are seen}
      while (position > 0) and
            (not (buffer[position] in [$0a, $0d])) do
      begin
        result := result + char(buffer[position]);
        checkforblockend;  {also increments/resets position}
      end;

      if   position > 0
      then begin
        {treating cr and lf individually, allows this class to be
         used with unix files with only lf separators instead of the
         usual cr lf separators.}

        if   buffer[position] = $0d   {cr occurs first when present}
        then checkforblockend;

        if   buffer[position] = $0a
        then checkforblockend;

      end

    end
  end {getline};

end.
0

ja napisałem taką funkcję! (pod delphi) działa dla dowolnego pliku :

function sprawdz_plik(s:string):boolean;
var plik:tfilestream;
b:boolean;
begin
b:=false;
try
plik:=tfilestream.create(s,fmopenwrite);
plik.free;
except
b:=true;
end;
if b then sprawdz_plik:=true else
sprawdz_plik:=false;
end;

użycie :

procedure TForm1.Button1Click(Sender: TObject);
begin
  if sprawdz_plik('c:\1.exe') then
    showmessage('jest używany')
  else
   showmessage('nie jest używany')
end;

a ten Wasz przykład! :

var
  f : textfile;
  Path : String;
begin
AssignFile (f,'C:\upx.exe');
{$I-} reset (f); {$I+}
 case IOResult of
  0 :  ShowMessage('Plik nie jest używany');
  2 :  ShowMessage('Nie ma wskazanego pliku');
  32 : ShowMessage('Plik jest używany !');
 end;
end;

gdy plik ma atrybut tylko_do_odczytu pokazuje, że jest używany a nie jest :]
trzeba to uwzględnić w ioresult

0
max hebda napisał(a)
function sprawdz_plik(s:string):boolean;
var plik:tfilestream;
    b:boolean;
begin
  b:=false;
  try
  plik:=tfilestream.create(s,fmopenwrite);
  plik.free;
  except
    b:=true;
  end;
   if b then sprawdz_plik:=true else
   sprawdz_plik:=false;
end;

Tylko, że trochę ona kulawa bo jak będzie błąd to plik się nie zwolni i zmiennych coś dużo

function sprawdz_plik(S: string): boolean;
var plik: TFileStream;
begin
  Result := True;
  try
    try
      plik := TFileStream.Create(S, fmOpenWrite);
    finally
      Plik.Free;
    end;
  except
    Result := False;
  end;
end;
0

To że plik można otworzyć nie oznacza, że nie jest używany, lecz jedynie nie jest zablokowany (lock lub open + exclusive itp.).

Jedyna metoda, to wycisnąć informację z systemu operacyjnego - on wie.

0

jeszcze mniejszy ;-)

function sprawdz_plik(S: string): boolean;
var plik: TFileStream;
begin
  Result := True;
    try
      plik := TFileStream.Create(S, fmOpenWrite);
      Plik.Free;
    except
      Result := False;
    end;
end;

a co do zwalniania pliku gdy błąd! jest poprawnie bo jesli jest problem z otwprzeniem to nie trzeba zwalniac :] czyli jeśli wystapi błąd nie jest konieczne zwalnianie wiec jest funkcja poprawna. tak jak w finally plik.free; bedzie wywołane tylko wtedy gdy nie ma błędu.

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