File handling

All except GUI problems

File handling

Postby Robert » Sat Sep 28, 2013 4:02 pm

Hi

I always assumed that if I wrote:

Code: Select all
  loc  :=  Files.dir.This ("D:\Data\ProjectX");

for example, and the path did not exist, that I would get loc = NIL.

However that does not seem to be the case.

What is the easiest way to test if a specific path exists?

Thanks

Robert
User avatar
Robert
 
Posts: 119
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: File handling

Postby Ivan Denisov » Sat Sep 28, 2013 4:20 pm

You can use Files.dir.LocList for that.

Example
Code: Select all
MODULE PrivTest;

   IMPORT  Log, Files;
   
   PROCEDURE Do*;
      VAR info: Files.LocInfo;
   BEGIN
      info  :=  Files.dir.LocList(Files.dir.This ("D:\Data\ProjectX"));
      IF info = NIL THEN
         Log.String("No such folder"); Log.Ln
      ELSE
         WHILE info.next # NIL DO
            Log.String(info.name); Log.Ln;
            info := info.next
         END
      END
   END Do;

END PrivTest.
User avatar
Ivan Denisov
 
Posts: 242
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: File handling

Postby Robert » Wed Nov 18, 2015 9:55 pm

Ivan

Thanks for the suggestion, but I don't think it works!

The "No such folder" string does not tell me that the stated folder does not exist, but rather that it has no sub-folders.


I know how to solve the problem (ie parse the folder string to strip off the last level, then call LocList, then scan the list for the stripped off bottom level).

The purpose of my question was to know if there is a simpler way.


Sorry for long (over two years) time to reply. I guess that this is not my most important problem!

Cheers,
Robert
User avatar
Robert
 
Posts: 119
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: File handling

Postby Robert » Thu Nov 19, 2015 9:11 pm

I tried another simple approach to check if a directory path exists:
Code: Select all
loc  :=  Files.dir.This ("D:\Data\ProjectX");
IF loc.res = 0 ...
because the Files Docu says that loc.res = 2 means "location or file not found".

This does not work either!
In fact in all my experiments loc is always non-NIL, and loc.res always equals 0 - "no error".

This makes me suspect that procedures such as StdDialog.GetSubLoc are buggy, as they seem to rely on loc = NIL for missing directories?

Robert

PS - I have just remembered that I solved this problem (years ago).
Call PathFileExistsW from shlwapi.dll:

Code: Select all
MODULE  CasketShlwapiDll ["shlwapi.dll"];
IMPORT  SYSTEM, Win := WinApi;
PROCEDURE  PathFileExistsW* (path : Win.PtrWSTR) : Win.BOOL;
END  CasketShlwapiDll.
with wrapper
Code: Select all
PROCEDURE  PathExists* (path : ARRAY OF CHAR) : BOOLEAN;
  VAR
    k, m  :  INTEGER;
    chr   :  CHAR;
  BEGIN
    k  :=  0; m  :=  -1;
    REPEAT
      chr  :=  path [k];
      IF  (chr = '/')  OR  (chr = '\')  THEN  m  :=  k  END;
      INC (k);
    UNTIL  chr  =  0X;
    path [m]  :=  0X;
    RETURN  Shlwapi.PathFileExistsW (path)  =  WinApi.TRUE
  END  PathExists;
User avatar
Robert
 
Posts: 119
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: File handling

Postby manumart1 » Fri Nov 20, 2015 8:52 am

You need to test the existence of a folder.
If you know that that folder will ALWAYS have a known file, then you can test for the existence of that file. If file does not exist, then folder does not exist.

For example, the file can be readme.txt, and have a content like this:
This file must be named "readme.txt" and must be in folder "C:\abc\def".
It is necessary for the proper functioning of the application.


Code: Select all
  VAR fLoc: Files.Locator; f: Files.File;

  fLoc := Files.dir.This("C:\abc\def");
  f := Files.dir.Old(fLoc, "readme.txt", Files.shared);
  IF fLoc.res # 0 THEN
    Error. Folder does not exist
  ELSE
    f.Close();
  END;


My answer is just an indirect way of knowing if a folder exists, and need to impose an obligation to the folder: to store a well known file.

Regards
manumart1
 
Posts: 66
Joined: Tue Sep 17, 2013 6:25 am

Re: File handling

Postby Robert » Sun Nov 22, 2015 5:28 pm

I think there are several problems with the solution I posted. My latest suggestion is
Code: Select all
MODULE  CasketShlwapiDll ["shlwapi.dll"];
IMPORT  SYSTEM, Win := WinApi;
PROCEDURE  PathIsDirectoryW* (path : Win.PtrWSTR) : Win.BOOL;
END  CasketShlwapiDll.
with a 'wrapper'
Code: Select all
PROCEDURE  TrimTail (VAR path : ARRAY OF CHAR);
  VAR
    k, m  :  INTEGER;
    chr   :  CHAR;
  BEGIN
    k  :=  0; m  :=  -1;
    REPEAT
      chr  :=  path [k];
      IF  (chr = '/')  OR  (chr = '\')  THEN  m  :=  k  END;
      INC (k)
    UNTIL  chr  =  0X;
    path [m + 1]  :=  0X   
  END  TrimTail;

PROCEDURE  IsDirectory* (path : ARRAY OF CHAR; trimTail : BOOLEAN) : BOOLEAN;
  BEGIN
    IF  trimTail  THEN  TrimTail (path)  END;
    RETURN  Shlwapi.PathIsDirectoryW (path)  #  WinApi.FALSE
  END  IsDirectory;
The option trimTail allows you to pass a full filename, and it will ignore the file part of the full path by cutting out anything after the last '/' or '\'.

This kind of file manipulation seems to be very difficult in BlackBox, but I seem to remember it was always difficult in every language I have ever used!

Cheers,
Robert
User avatar
Robert
 
Posts: 119
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: File handling

Postby manumart1 » Mon Nov 23, 2015 11:09 am

Your procedure TrimTrail is similar to HostFiles.GetPath, that is not exported.
Code: Select all
MODULE HostFiles;
...
PROCEDURE GetPath (IN fname: FullName; OUT path: FullName);
   VAR i: INTEGER;
BEGIN
   path := fname$; i := LEN(path$);
   WHILE (i > 0) & (path[i] # "\") & (path[i] # "/") & (path[i-1] # ":") DO DEC(i) END;
   path[i] := 0X
END GetPath;
manumart1
 
Posts: 66
Joined: Tue Sep 17, 2013 6:25 am

Re: File handling

Postby Josef Templ » Wed Nov 25, 2015 3:00 pm

It may make sense indeed to add two functions "IsFile" and "IsDir" to Files.Locator.
They would return TRUE if and only if the locator exists and represents a file resp. a directory.
Similar functions are also available in Java, for example.

- Josef
Josef Templ
 
Posts: 218
Joined: Tue Sep 17, 2013 6:50 am

Re: File handling

Postby Robert » Wed Nov 25, 2015 7:31 pm

Josef Templ wrote:It may make sense indeed to add two functions ...

I have a list of 5 that I think are of general utility and I find difficult in standard BlackBox.

Whether they should be associated with Locators, or Module Files, or a non-standard BlackBox library in Cpc for example is a different discussion.

Their interfaces are
Code: Select all
PROCEDURE CopyFile (IN srcName, dstName: ARRAY OF CHAR; buildPath, allowOverwrite: BOOLEAN): BOOLEAN;
PROCEDURE CreateDirectory (IN path: ARRAY OF CHAR): BOOLEAN;
PROCEDURE CreatePath (IN path: ARRAY OF CHAR; trimTail: BOOLEAN; OUT cnt: INTEGER);
PROCEDURE IsDirectory (path: ARRAY OF CHAR; trimTail: BOOLEAN): BOOLEAN;
PROCEDURE PathFileExists (name: ARRAY OF CHAR; trimTail: BOOLEAN): BOOLEAN;


If anyone is interested I can send them the full Docu & Mod files.

Regards
Robert
User avatar
Robert
 
Posts: 119
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland


Return to BlackBox Framework

Who is online

Users browsing this forum: No registered users and 1 guest

cron