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.
do it on a NETWORK mapped drive you get this:
you will notice that there is an epub file there.. its a file. not a folder.
Error with dir(filespec, attrib)
Re: Error with dir(filespec, attrib)
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/
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/
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: Error with dir(filespec, attrib)
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.
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.
Re: Error with dir(filespec, attrib)
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.
So its not an exclusion issue, its actually thinking files are also folders.
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: Error with dir(filespec, attrib)
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:
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
Re: Error with dir(filespec, attrib)
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.
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.