Error with dir(filespec, attrib)

Windows specific questions.
Post Reply
Rainwulf
Posts: 35
Joined: Mar 28, 2007 11:33

Error with dir(filespec, attrib)

Post by Rainwulf »

Interesting error thats easy to reproduce.

with:
chdir "c:\"
attrib = 16+2+1
fileName= dir$("*", attrib)
print fileName
do
fileName=dir$("", attrib)
print fileName
loop while fileName <> ""

on a LOCAL hard drive, it returns ONLY directories.

do it on a network mapped drive, and it returns both directories and files.


Image

do it on a NETWORK mapped drive you get this:

Image

you will notice that there is an epub file there.. its a file. not a folder.
Rainwulf
Posts: 35
Joined: Mar 28, 2007 11:33

Re: Error with dir(filespec, attrib)

Post by Rainwulf »

wait. i did some more investigation.
It doesnt do it if the mapped drive is mapped from a WINDOWS share but if the mapped drive is mapped from a FREENAS share (samba) it does that weird behaviour.


Looks like its a bug with samba. fantastic!

It however does work fine with windows explorer, so maybe freebasic's version of "dir" does it a different way.

I cant work out a way around this either, so im going to have to live with it :(

edit: some more information!

https://forums.freenas.org/index.php?th ... nce.24906/
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Error with dir(filespec, attrib)

Post by counting_pine »

KeyPgDir
Because of the way the attribute mask works, Dir("*", 16+2+1) will exclude any files if they contain attributes other than those listed (Directory, Hidden, Read-only).

(Dir will also include non-directories as well as visible and writable files, as long as they have no other attributes)

My suspicion is that the FreeNAS is also setting the Archive bit on those files, which is causing Dir to exclude them from the results. You can test this by calling Dir("*", &h3f, out_attrib) and Dir(out_attrib), and checking the bits set in out_attrib. An archived file will match against &h20 ('(out_attrib AND &h20) <> 0').

I suspect that in practice the attrib_mask parameter rarely gives people the control they want, and instead it is better to also pass an out_attrib parameter (by reference), which will return the file's attributes, and allow the program to run further tests on the attributes to decide whether or not to exclude them.
Rainwulf
Posts: 35
Joined: Mar 28, 2007 11:33

Re: Error with dir(filespec, attrib)

Post by Rainwulf »

But the issue isnt that im missing information, its just that its actually providing too MUCH information and returning files as both files AND folders.

So its not an exclusion issue, its actually thinking files are also folders.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Error with dir(filespec, attrib)

Post by counting_pine »

Sorry, I didn't read carefully. So I suspect the NAS is listing files (non-folders) with the archive attribute unset, while the Windows folder is listing files with the archive attribute set, and it's this attribute that's causing files to be excluded from the results.

It still stands that using the first attributes flag alone, doesn't give the kind of results most people want. It only tells Dir() what results you want to include, but doesn't explicitly allow you to exclude anything.

If you were to pass &h10 (fbDirectory) on its own, you would be telling Dir that you want to include directories in the results, not that you want to exclude files from the results.

If a file has no attributes set (not archived, hidden, system, or read-only), then there is actually no way to exclude it from Dir()'s results.

You have to set the attrib_mask to be at least as inclusive as you need it to be, and also pass the out_attrib value and check its bits.

There's an example on the wiki page about how to use Dir effectively. It's a little on the long side, but this (non-compilable) extract contains the important bits:

Code: Select all

Do Until Len(fname) = 0 '' loop until Dir returns empty string

    If (fname <> ".") And (fname <> "..") Then '' ignore current and parent directory entries

        Print fname,

        If (out_attr And fbDirectory) <> 0 Then
            Print "- directory";
            dircount += 1
        Else
            Print "- file";
            filecount += 1
        End If
        If (out_attr And fbReadOnly) <> 0 Then Print ", read-only";
        If (out_attr And fbHidden  ) <> 0 Then Print ", hidden";
        If (out_attr And fbSystem  ) <> 0 Then Print ", system";
        If (out_attr And fbArchive ) <> 0 Then Print ", archived";
        Print

    End If

    fname = Dir(out_attr) '' find next name/attributes

Loop
Rainwulf
Posts: 35
Joined: Mar 28, 2007 11:33

Re: Error with dir(filespec, attrib)

Post by Rainwulf »

Thank you! I will try that out and see if it works on my code.

My program allows you to treat filenames as text, so if you need to mass rename a set of files, for example include a new character, or change a certain set of characters, or even search and replace, it can do all the changes on the files as one.

I made it to edit media files that have things like "Name 5x01.mkv' to change it to 'Name [05x01].mkv' and do it to an entire folder instead of one file name at at time.
Post Reply