Author Topic: What to do about non ASCII characters in file names?  (Read 5053 times)

0 Members and 1 Guest are viewing this topic.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
What to do about non ASCII characters in file names?
« on: September 14, 2018, 06:27:21 pm »
So i've made good headway on my duplicate file finder program to help clean up my polluted disk drive. but have hit a snag with files that contain non-ASCII characters like the example below:
"[Audio-4U] 妖精帝國 — Yousei Teikoku 2.0 (vorbis)"

which turns into this in the IDE:
"[Audio-4U] ???? — Yousei Teikoku 2.0 (vorbis)"

which cannot be found, and causes my program to crash. is there anyway to get the IDE to handle characters like the ones above(Japanese Kanji) or will I need to figure out how to code something that will "identify" these directories and files and skip them? Not that any of my text editors can handle those characters so might be mute to try but I'm willing to give it a go, if its possible.
Granted after becoming radioactive I only have a half-life!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #1 on: September 14, 2018, 11:29:57 pm »
IF INSTR(filename$, "?") THEN  ' skip this file

Look for invalid characters in the string first before trying to process it perhaps. Any invalid character will cause the file name to be skipped.

or

IF NOT _FILEEXISTS(filename$) THEN 'skip this file
« Last Edit: September 14, 2018, 11:31:07 pm by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #2 on: September 15, 2018, 12:20:51 am »
IF INSTR(filename$, "?") THEN  ' skip this file
Look for invalid characters in the string first before trying to process it perhaps. Any invalid character will cause the file name to be skipped.
or
IF NOT _FILEEXISTS(filename$) THEN 'skip this file

yeah I tried the INSTR made it farther but still failed, trying the _FILEEXISTS now. be an hour or so before it hits the last fail point.

anybody know why this line more than doubles the time the program takes to run a cycle?
    IF RTRIM$(FFiles(1).NameL) = RTRIM$(FFiles(0).NameL) THEN
unless the file names match it does nothing, yet it increases the cycle time just over 100%(1.019 sec to 2.25 secs per cycle)
is RTRIM$ really that slow?
Granted after becoming radioactive I only have a half-life!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #3 on: September 15, 2018, 01:02:18 am »
Perhaps setting a predetermined length for your string will eliminate the need for RTRIM$()

The example below shows that it does not matter how many trailing spaces there are, they still equal.

Code: QB64: [Select]
  1. TYPE test
  2.     NameL AS STRING * 255
  3.  
  4. DIM FFiles(2) AS test
  5.  
  6. FFiles(1).NameL = "This is a test      "
  7. FFiles(2).NameL = "This is a test"
  8.  
  9. IF FFiles(1).NameL = FFiles(2).NameL THEN PRINT "Yes"
In order to understand recursion, one must first understand recursion.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: What to do about non ASCII characters in file names?
« Reply #4 on: September 15, 2018, 01:34:00 am »
Or Trim it outside of the loop if they're DIM AS STRING.

FOR I = 1 TO LIMIT
    FFiles(I).NameL = RTRIM$(FFiles(I).NameL)
NEXT

Then do the IFs and all.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #5 on: September 15, 2018, 03:33:03 am »
Hello Cobalt.

File omission would mean having a program that is not 100 percent. So I'll ask about the nature of the problem. How do you get a list of files on a disk? Are you using Linux and / or Windows? I have solved the same problem. When a file was found in UNICODE, an invalid name was returned.
There are two ways I tried, one is complicated and the other one even more. The first method I obtained from a disk listing was full list with DIR, but after the tests I found out that this listing is not the same in all windows. Ashish pointed out to me that his DIR is 2-bytes shifted to the right compared to my DIR listing, and that caused great problems. To access the files, I used the 8.3 format listings, but I used the full name to display the file name (after the required font and the transcription using _MAPUNICODE). This is a tricky approach that works.

The other way showed me Eoredson. Erik wrote a program using Windows libraries to print and access all the files on the disk correctly (first but use correct _MAPUNICODE block for correct on screen view, but as file acces it work). I made a simple textual interface for that. This way should work properly everywhere. I give this program here, first find the files if they are displayed correctly (after _MAPUNICODE use) but as acces it works so at is is. If you have any questions, I will try to answer, but with regard to libraries, Erik knows more details because he is the author of the program kernel.

try use MP3 file contains unicode charcters in folder/file name for show, that fileacces works correctly. Just find it and press enter.

Code: QB64: [Select]
  1. 'info:
  2. ' FileNames array contains long file names without path
  3. ' ShortNames array contains short file names without path
  4. ' Directories array contains long directories names without path
  5. ' ShortNameDir array contains short directories names without path
  6. ' FUNCTION  __File$ (mask$, parameter)  - if is parameter 1, this function return SHORT filename AND PATH to this file (after is this file with Enter selected)
  7. '                                       - if is parameter 2, return 2 arrays (STRING): first array is FilesVisible. Contains long filesnames + path. Second is FilesUsable. Contains short filesnames + path.
  8. '                                       - in X$ = __Files$ (mask$, 2) you need NOT X$, is for call only. In this mode select more files using Enter and then go back pressing Esc.
  9. '                                      in function __Files$ use arrow Up and Down, PageUP, PageDN, Home, End, Enter and Esc. Is possible switching drives and selecting files in more places not in 1 dir only!
  10.  
  11. ' Please test it. Use UNICODE paths, UNICODE filenames, for real hard test. For me all works correctly.
  12.  
  13.  
  14. 'typy a zpusoby navratu: - vrati seznam souboru ze slozky formou pole  ---- v poli FileNames - dlouha jmena, ShortNameFile vraci kratka jmena
  15. '                        - vrati seznam adresaru                       ---- v poli Directories dlouha jmena, ShortNameDir vraci kratka jmena adresaru
  16. '                        - vrati jeden soubor po vyberu (soucasny stav)  -- __Files (mask$, 1)
  17. '                        - vrati vice souboru po vyberu               ----- __Files (mask$, 2)
  18.  
  19. 'this program in main loop contains _SNDPLAY statement, so please try selecting and then playing some your MP3 files using your national unicode names.
  20.  
  21.  
  22.  
  23.  
  24. REM sample program to get/list/sort lists of filenames/directories v1.0a PD. Upgraded Erik's code for solving FILES statement unusuality.
  25. ' detect operating system
  26. $IF WIN = 0 THEN
  27.     COLOR 15, 0
  28.     CLS
  29.     PRINT "Sorry, this program only works in Windows.."
  30.     END
  31. CONST MAX_PATH = 260
  32. CONST INVALID_HANDLE_VALUE = -1
  33. CONST ERROR_FILE_NOT_FOUND = 2
  34. CONST ERROR_NO_MORE_FILES = &H12
  35.  
  36.  
  37.  
  38.  
  39.  
  40. TYPE FILETIME
  41.     dwLowDateTime AS _UNSIGNED LONG
  42.     dwHighDateTime AS _UNSIGNED LONG
  43.  
  44. TYPE SYSTEMTIME
  45.     wYear AS INTEGER
  46.     wMonth AS INTEGER
  47.     wDayOfWeek AS INTEGER
  48.     wDay AS INTEGER
  49.     wHour AS INTEGER
  50.     wMinute AS INTEGER
  51.     wSecond AS INTEGER
  52.     wMilliseconds AS INTEGER
  53.  
  54. TYPE WIN32_FIND_DATAA
  55.     dwFileAttributes AS _UNSIGNED LONG
  56.     ftCreationTime AS FILETIME
  57.     ftLastAccessTime AS FILETIME
  58.     ftLastWriteTime AS FILETIME
  59.     nFileSizeHigh AS _UNSIGNED LONG
  60.     nFileSizeLow AS _UNSIGNED LONG
  61.     dwReserved0 AS _UNSIGNED LONG
  62.     dwReserved1 AS _UNSIGNED LONG
  63.     cFileName AS STRING * MAX_PATH
  64.     cAlternateFileName AS STRING * 14
  65.  
  66.     FUNCTION FindFirstFileA~%& (BYVAL lpFileName~%&, BYVAL lpFindFileData~%&)
  67.     FUNCTION FindNextFileA& (BYVAL hFindFile~%&, BYVAL lpFindFileData~%&)
  68.     FUNCTION FindClose& (BYVAL hFindFile~%&)
  69.     FUNCTION FileTimeToSystemTime& (lpFileTime AS FILETIME, lpSystemTime AS SYSTEMTIME)
  70.     FUNCTION GetVolumeInformationA& (lpRootPathName$, lpVolumeNameBuffer$, BYVAL nVolumeNameSize~&, lpVolumeSerialNumber~&, lpMaximumComponentLength~&, lpFileSystemFlags~&, lpFileSystemNameBuffer$, BYVAL nFileSystemNameSize&)
  71.     FUNCTION GetDiskFreeSpaceA& (f$, sectors&, bytes&, free&, total&)
  72.     FUNCTION GetDiskFreeSpaceExA& (filename$, free AS _UNSIGNED _INTEGER64, total AS _UNSIGNED _INTEGER64, free2 AS _UNSIGNED _INTEGER64)
  73.  
  74.     FUNCTION GetFileAttributes& (f$)
  75.     FUNCTION SetFileAttributes& (f$, BYVAL a&)
  76.     FUNCTION GetDriveType& (d$)
  77.     FUNCTION GetShortPathName& (InP$, OutP$, BYVAL length&)
  78.     FUNCTION GetModuleFileNameA (BYVAL Module AS LONG, FileName AS STRING, BYVAL nSize AS LONG)
  79.  
  80. ' declare library variables.
  81. DIM SHARED finddata AS WIN32_FIND_DATAA
  82. DIM SHARED SysTime AS SYSTEMTIME
  83. DIM SHARED DriveType AS STRING
  84.  
  85. ' declare byte divisor variable.
  86. DIM SHARED ByteDivisor AS DOUBLE
  87. '--------------------------------
  88. 'moje vklady
  89. DIM SHARED Drives(1) AS STRING 'vrati pole s pismeny jednotek
  90. DIM SHARED DriveLabels(1) AS STRING
  91. DIM SHARED DriveSerials(1) AS STRING
  92. DIM SHARED DriveType(1) AS STRING
  93. DIM SHARED DiskTotalSpace(1) AS STRING
  94. DIM SHARED DiskFreeSpace(1) AS STRING
  95.  
  96.  
  97. DIM SHARED Filenames(1) AS STRING
  98. DIM SHARED Directories(1) AS STRING
  99.  
  100. DIM SHARED FileCount AS SINGLE
  101. DIM SHARED DirCount AS SINGLE
  102.  
  103. DIM SHARED FileSize(1) AS DOUBLE
  104.  
  105. DIM SHARED DateTimeDir(1) AS STRING * 19
  106. DIM SHARED DateTimeFile(1) AS STRING * 19
  107.  
  108. DIM SHARED AttributesDir(1) AS INTEGER
  109. DIM SHARED AttributesFile(1) AS INTEGER
  110.  
  111. DIM SHARED ShortNameDir(1) AS STRING
  112. DIM SHARED ShortNameFile(1) AS STRING
  113.  
  114. DIM SHARED DateTimeType AS INTEGER
  115. DIM SHARED LineCount AS INTEGER
  116.  
  117. REDIM SHARED FilesVisible(1) AS STRING 'pro vicenasobny vyber - dlouha jmena 'multiple select array, long names + path
  118. REDIM SHARED FilesUsable(1) AS STRING 'pro vicenasobny vyber - kratka jmena  'multiple select array, short names + path
  119.  
  120. REDIM SHARED Attrib(1) AS STRING
  121.  
  122. DateTimeType = 1
  123. StoreSort1 = 1
  124. StoreSort2 = -1
  125.  
  126. ' ------------ start mych uprav ------------- Petr's upgrade start
  127.  
  128.  
  129. rst:
  130. Maska$ = "*.mp3" 'mask
  131. CALL GetFiles(Maska$) '                 load files list from kernel32 to memory, Erik work
  132. CALL SortFiles(StoreSort1, StoreSort2) 'sort files, Erik work
  133. REDIM SHARED Adresar(0) AS STRING 'its help array, Petr work - for Dirs
  134. REDIM SHARED Soubor(0) AS STRING ' its help array, Petr work - for files
  135.  
  136.  
  137.  
  138. 'telo programu disk
  139. ON ERROR GOTO Error.Routine
  140. ' declare some constants.
  141. CONST Nul = ""
  142. CONST True = -1
  143. _TITLE "DRIVE INFO"
  144.  
  145. REM Start program loop.
  146.  
  147. IF INSTR(_OS$, "[WINDOWS]") THEN
  148.     ByteDivisor = 1024
  149.     IF INSTR(_OS$, "[MACOSX]") THEN
  150.         ByteDivisor = 1000
  151.     ELSE
  152.         ByteDivisor = 1024
  153.     END IF
  154.  
  155.  
  156. ListDrives Nul, 0
  157. ListFiles
  158. 'telo disk konec
  159.  
  160. SCREEN _NEWIMAGE(640, 480, 256)
  161. one$ = __Files$("*.*", 1) '__Files$ (function) is Petr's program full based on Erik's demo.
  162. CLS '
  163. PRINT "Function return this path to 1 selected file: "; one$
  164. IF LCASE$(RIGHT$(one$, 4)) = ".mp3" THEN m& = _SNDOPEN(one$): _SNDPLAY m& ELSE _SCREENICON: SHELL one$
  165. PRINT "Select more files with enter, quit with Esc"
  166. e$ = __Files$("*.mp3", 2): e$ = "" 'function return with ,2 outputs in arrays FilesVisible and FilesUsable
  167. PRINT "Selected files:"
  168. PRINT "Long names (use with _MAPUNICODE NOT FOR ACCESS! and short system name, use for access:):"
  169.  
  170. FOR w = 0 TO UBOUND(FilesVisible)
  171.     COLOR 15
  172.     PRINT FilesVisible(w); CHR$(32);: COLOR 4: PRINT FilesUsable(w)
  173.     IF w MOD 5 = 0 AND w >= 5 THEN COLOR 15: PRINT "Press any key...": SLEEP: CLS: PRINT "Long names (use with _MAPUNICODE NOT FOR ACCESS! and short system name, use for access:):"
  174. PRINT "After pressing key, sound will stopped and is played selected from mode 2 (if are some MP3 selected)"
  175. COLOR 15, 0
  176.  
  177. FOR w = 1 TO UBOUND(FilesVisible)
  178.     IF LCASE$(RIGHT$(FilesUsable(w), 4)) = ".mp3" THEN
  179.         m& = _SNDOPEN(FilesUsable(w))
  180.         _SNDPLAY m&
  181.         DO UNTIL NOT _SNDPLAYING(m&)
  182.             i$ = INKEY$
  183.             IF i$ = CHR$(27) THEN END
  184.             LOCATE 5, 1: PRINT "Playing "; FilesVisible(w)
  185.             LOCATE 6, 1: PRINT FilesUsable(w)
  186.             _LIMIT 10
  187.         LOOP
  188.         IF m& THEN _SNDCLOSE m&
  189.         CLS
  190.     END IF
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197. ' critical error trap
  198. Error.Routine:
  199.  
  200. FUNCTION __Files$ (mask AS STRING, typ AS _BYTE) 'mask - use "*.*" for all files.... typ: 1 for one file select, 2 for more files (and it can be in different directories) selecting, this is ending after pressing Esc, values are then in arrays FilesVisible and FilesUsable. Visible for long names viewing, Usable for file access!  THIS MUSS WORKING ON ALL WINDOWS WORLDWIDE!
  201.  
  202.     begin:
  203.     DirLevel = 0
  204.     sizindex = 1
  205.     CLS
  206.     path$ = _CWD$
  207.     IF _PIXELSIZE = 0 THEN LOCATE 1, 1: PRINT "Current path: "; path$
  208.  
  209.     GetFiles mask$
  210.     SortFiles StoreSort1, StoreSort2
  211.     REDIM Adresar(DirCount) AS STRING '             Directories
  212.     REDIM Soubor(FileCount) AS STRING '             Files
  213.     REDIM Vse(DirCount + FileCount) AS STRING '     Both - first directories, then files - contains long names, unussable for stable file access in other as english languages (not coded in Unicode)
  214.     REDIM Acces(UBOUND(vse)) AS STRING '            Both - short names, usable for worldwide file / folder access
  215.     REDIM ostatni(UBOUND(vse)) AS STRING 'date and time
  216.     REDIM Attrib(FileCount + DirCount) AS STRING
  217.     REDIM Size(FileCount) AS STRING
  218.     ListDirs '                                                              modified - give dir names to array adresar$
  219.     ListFiles '                                                             modified - give long file names to array soubor$
  220.     akt = 1
  221.     vklad = 1
  222.     FOR rew0 = 1 TO DirCount
  223.         Vse(rew0) = UCASE$(Adresar(rew0))
  224.         ostatni(rew0) = DateTimeDir(rew0)
  225.         IF ShortNameDir(rew0) <> "" THEN Acces(rew0) = ShortNameDir(rew0) ELSE Acces(rew0) = UCASE$(Directories(rew0))
  226.     NEXT rew0
  227.     FOR rew1 = 1 TO FileCount
  228.         Vse(DirCount + rew1) = Soubor(rew1)
  229.         ostatni(DirCount + rew1) = DateTimeFile(rew1)
  230.         IF ShortNameFile(rew1) <> "" THEN Acces(DirCount + rew1) = ShortNameFile(rew1) ELSE Acces(DirCount + rew1) = Filenames(rew1)
  231.     NEXT rew1
  232.  
  233.     IF LEN(path$) > 3 THEN REDIM _PRESERVE Vse(UBOUND(vse) + 1) AS STRING: Vse(UBOUND(vse)) = ".." '.. is for return up one level in directory structure
  234.  
  235.     Celkem = UBOUND(vse)
  236.     IF Celkem < 1 THEN Celkem = 1
  237.     ListStart = 1
  238.     ListEnd = 15
  239.     pul = CINT(ListEnd - ListStart) / 2
  240.     IF ListEnd > Celkem THEN ListEnd = Celkem
  241.     akt = 1 'what is selected. First name in list after start
  242.     vypis = 1
  243.     Pso = 5 ' start printing folder list. This number muss be the same as in line 177!
  244.  
  245.     REDIM _PRESERVE ostatni(UBOUND(vse)) AS STRING
  246.     DO
  247.         FOR vypis = ListStart TO ListEnd
  248.             IF ListEnd > UBOUND(vse) THEN ListEnd = UBOUND(vse)
  249.             Pso = Pso + 1
  250.             i$ = INKEY$
  251.             SELECT CASE i$
  252.                 CASE CHR$(0) + CHR$(72)
  253.                     akt = akt - 1: IF akt < 1 THEN akt = 1
  254.                     IF akt < pul + ListStart THEN ListStart = ListStart - 1: ListEnd = ListEnd - 1
  255.                     IF ListStart < 1 THEN ListStart = 1: ListEnd = ListStart + (ListEnd - ListStart + 1)
  256.                 CASE CHR$(0) + CHR$(80)
  257.                     akt = akt + 1: IF akt > Celkem THEN akt = Celkem
  258.                     IF akt > pul + ListStart THEN ListEnd = ListEnd + 1: ListStart = ListStart + 1
  259.                     IF ListEnd > UBOUND(vse) THEN ListEnd = UBOUND(vse): ListStart = ListEnd - (ListEnd - ListStart + 1)
  260.                 CASE CHR$(0) + CHR$(71): akt = 1: ListStart = 1: IF UBOUND(vse) > 15 THEN ListEnd = 15 ELSE ListEnd = UBOUND(vse) 'home
  261.                 CASE CHR$(0) + CHR$(79): akt = UBOUND(vse): ListEnd = akt: IF akt > 15 THEN ListStart = akt - 15 ELSE ListStart = 1 ' end
  262.                 CASE CHR$(0) + CHR$(73) 'pgUp
  263.                     akt = akt - 15: IF akt < 1 THEN akt = 1
  264.                     ListStart = ListStart - 15
  265.                     IF ListStart < 1 THEN ListStart = 1
  266.                     IF ListStart + 15 < UBOUND(vse) THEN ListEnd = ListStart + 15 ELSE ListEnd = UBOUND(vse)
  267.                 CASE CHR$(0) + CHR$(81)
  268.                     akt = akt + 15: IF akt > UBOUND(vse) THEN akt = UBOUND(vse)
  269.                     ListEnd = ListEnd + 15
  270.                     IF ListEnd > UBOUND(vse) THEN ListEnd = UBOUND(vse)
  271.                     IF ListEnd - 15 > 1 THEN ListStart = ListEnd - 15 ELSE ListStart = 1
  272.                 CASE CHR$(13)
  273.                     SELECT CASE typ
  274.                         CASE 1: EXIT DO
  275.                         CASE 2:
  276.                             IF Vse(akt) = ".." THEN CHDIR "..": DirLevel = DirLevel - 1: t$ = "": GOTO begin
  277.                             IF akt <= DirCount THEN CHDIR Acces(akt): DirLevel = DirLevel + 1: t$ = "": GOTO begin ' CHDIR MUSS BE!!!!! set to Acces array for long DIRECTORIES names!!!!
  278.                             zaznam = zaznam + 1
  279.                             REDIM _PRESERVE FilesVisible(zaznam) AS STRING: FilesVisible(zaznam) = path$ + CHR$(92) + Vse(akt)
  280.                             REDIM _PRESERVE FilesUsable(zaznam) AS STRING: FilesUsable(zaznam) = path$ + CHR$(92) + Acces(akt)
  281.                     END SELECT
  282.                 CASE CHR$(27): IF typ = 2 THEN _AUTODISPLAY: EXIT FUNCTION
  283.             END SELECT
  284.             IF LEN(useavailable$) THEN
  285.                 FOR fr = 1 TO LEN(useavailable$)
  286.                     IF MID$(UCASE$(useavailable$), fr, 1) = UCASE$(i$) THEN disc = fr: DriveSelect$ = i$ + LTRIM$(":\"): CHDIR DriveSelect$: GOTO begin
  287.                 NEXT fr
  288.             END IF
  289.             COLOR 15, 0: LOCATE Pso, 20: PRINT SPACE$(55)
  290.             IF vypis = akt THEN COLOR 14, 9 ELSE COLOR 15, 0
  291.             IF LEN(Vse(vypis)) > 24 THEN t$ = LEFT$(Vse(vypis), 21) + "..." ELSE t$ = Vse(vypis)
  292.             IF vypis > UBOUND(vse) THEN
  293.                 navic$ = ""
  294.             ELSE
  295.                 navic$ = ostatni(vypis)
  296.             END IF
  297.  
  298.             IF t$ = ".." THEN t$ = t$ + SPC(57)
  299.  
  300.             IF typ = 2 THEN
  301.                 FOR porovnej = 0 TO UBOUND(FilesVisible)
  302.                     IF FilesVisible(porovnej) = path$ + CHR$(92) + Vse(vypis) THEN COLOR 2 'musi byt shoda i s cestou
  303.                     IF FilesUsable(porovnej) = path$ + CHR$(92) + Vse(vypis) THEN COLOR 2
  304.                 NEXT
  305.             END IF
  306.             IF vypis > DirCount AND vypis <= FileCount + DirCount THEN
  307.                 LOCATE Pso, 54: PRINT "  "; Attrib(vypis - DirCount) + SPC(14) ' atributy   [pole attrib je velke jako dircount + filecount]
  308.                 LOCATE Pso, 63: PRINT Size(vypis - DirCount)
  309.             ELSE LOCATE Pso, 54: PRINT " <DIR> " + SPC(12)
  310.             END IF
  311.             LOCATE Pso, 10: PRINT t$; SPC(25 - LEN(t$)); navic$; CHR$(32)
  312.             COLOR 15, 0
  313.         NEXT vypis
  314.         i3 = 0
  315.         Pso = 5
  316.         sizindex = 0
  317.  
  318.         IF _PIXELSIZE > 0 THEN
  319.             LINE (30, 30)-(610, 360), 15, B
  320.             LINE (35, 35)-(605, 355), 15, B
  321.             LINE (35, 60)-(605, 65), 15, B
  322.             _PRINTSTRING (40, 40), "         Select file. Use Esc in mode 2 for end. Mode: " + STR$(typ)
  323.  
  324.             IF LEN(path$) > 44 THEN pat$ = LEFT$(path$, 44) + "..." ELSE pat$ = path$
  325.             _PRINTSTRING (70, 370), "Current path: " + pat$
  326.             LINE (610, 360)-(30, 395), 15, B
  327.             LINE (605, 360)-(35, 390), 15, B
  328.             IF Available$ = "" THEN
  329.                 FOR HowDisk = 1 TO UBOUND(drives)
  330.                     IF UCASE$(LEFT$(pat$, 1)) = UCASE$(Drives(HowDisk)) THEN disc = HowDisk
  331.                     Available$ = Available$ + Drives(HowDisk) + " "
  332.                     useavailable$ = useavailable$ + Drives(HowDisk)
  333.                 NEXT
  334.             END IF
  335.             _PRINTSTRING (30, 400), "Disk info: " + Drives(disc) + LTRIM$(":\  Total space: ") + DiskTotalSpace(disc) + " Free space: " + DiskFreeSpace(disc) + RTRIM$(" [" + DriveLabels(disc) + "]")
  336.             _PRINTSTRING (30, 420), "Press correct key for select drive. Drives: " + Available$
  337.         END IF
  338.         _DISPLAY
  339.         _LIMIT 15
  340.     LOOP
  341.     IF Vse(akt) = ".." THEN CHDIR "..": DirLevel = DirLevel - 1: t$ = "": GOTO begin
  342.     IF akt <= DirCount THEN CHDIR Acces(akt): DirLevel = DirLevel + 1: GOTO begin
  343.     IF akt <= DirCount THEN __Files$ = path$ + CHR$(92) + Acces(akt) ELSE __Files$ = path$ + CHR$(92) + Acces(akt)
  344. SUB GetFiles (Var$)
  345.     maska$ = Var$
  346.     Var$ = "*.*"
  347.     DIM Attribute AS INTEGER
  348.     DIM ASCIIZ AS STRING * 260
  349.     DIM finddata AS WIN32_FIND_DATAA
  350.     DIM Wfile.Handle AS _UNSIGNED _OFFSET
  351.     DIM SysTime AS SYSTEMTIME
  352.  
  353.     DirCount = 0!
  354.     FileCount = 0!
  355.  
  356.     ASCIIZ = Var$ + CHR$(0)
  357.     Wfile.Handle = FindFirstFileA(_OFFSET(ASCIIZ), _OFFSET(finddata))
  358.     IF Wfile.Handle <> INVALID_HANDLE_VALUE THEN ' OR WDIR.Handle <> INVALID_HANDLE_VALUE THEN
  359.         DO
  360.             Attribute = finddata.dwFileAttributes
  361.             Filename$ = finddata.cFileName
  362.             Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  363.             IF Filename$ <> "." AND Filename$ <> ".." THEN
  364.  
  365.                 ' store date/time
  366.                 SELECT CASE DateTimeType
  367.                     CASE 1
  368.                         x& = FileTimeToSystemTime&(finddata.ftCreationTime, SysTime)
  369.                     CASE 2
  370.                         x& = FileTimeToSystemTime&(finddata.ftLastAccessTime, SysTime)
  371.                     CASE 3
  372.                         x& = FileTimeToSystemTime&(finddata.ftLastWriteTime, SysTime)
  373.                 END SELECT
  374.  
  375.                 Var1$ = RIGHT$("00" + LTRIM$(STR$(SysTime.wMonth)), 2) + "-"
  376.                 Var1$ = Var1$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wDay)), 2) + "-"
  377.                 Var1$ = Var1$ + LTRIM$(STR$(SysTime.wYear)) + " "
  378.  
  379.                 Var1$ = Var1$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wHour)), 2) + ":"
  380.                 Var1$ = Var1$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wMinute)), 2) + ":"
  381.                 Var1$ = Var1$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wSecond)), 2)
  382.                 IF (Attribute AND &H10) = &H10 THEN
  383.                     DirCount = DirCount + 1!
  384.                     REDIM _PRESERVE Directories(DirCount) AS STRING
  385.                     Directories(DirCount) = Filename$
  386.  
  387.                     REDIM _PRESERVE DateTimeDir(DirCount) AS STRING * 19
  388.                     DateTimeDir(DirCount) = Var1$
  389.  
  390.                     REDIM _PRESERVE AttributesDir(DirCount) AS INTEGER
  391.                     AttributesDir(DirCount) = Attribute
  392.  
  393.                     Filename$ = finddata.cAlternateFileName
  394.                     Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  395.                     REDIM _PRESERVE ShortNameDir(DirCount) AS STRING
  396.                     ShortNameDir(DirCount) = Filename$
  397.                 ELSE
  398.                     FileCount = FileCount + 1!
  399.                     REDIM _PRESERVE Filenames(FileCount) AS STRING
  400.                     Filenames(FileCount) = Filename$
  401.                     REDIM _PRESERVE FileSize(FileCount) AS DOUBLE
  402.                     F# = finddata.nFileSizeHigh * &H100000000~&& OR finddata.nFileSizeLow
  403.                     FileSize(FileCount) = F#
  404.  
  405.                     REDIM _PRESERVE DateTimeFile(FileCount) AS STRING * 19
  406.                     DateTimeFile(FileCount) = Var1$
  407.  
  408.                     REDIM _PRESERVE AttributesFile(FileCount) AS INTEGER
  409.                     AttributesFile(FileCount) = Attribute
  410.  
  411.                     Filename$ = finddata.cAlternateFileName
  412.                     Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  413.                     REDIM _PRESERVE ShortNameFile(FileCount) AS STRING
  414.                     ShortNameFile(FileCount) = Filename$
  415.                 END IF
  416.             END IF
  417.         LOOP WHILE FindNextFileA(Wfile.Handle, _OFFSET(finddata))
  418.         x = FindClose(Wfile.Handle)
  419.     END IF
  420.     IF maska$ <> "*.*" THEN Var$ = maska$: Filtruj maska$ 'prepise FileCount podle predimenzovaneho poctu zanamu do poli FileNames, FileSize, DateTimeFile a ShortNameFile. Zaznamy adresaru zustanou stejne!
  421.  
  422.  
  423. ' Var1=1 filename, Var1=2 datetime, Var1=3 filesize
  424. ' Var2=-1 ascending, Var2=0 descending
  425. SUB SortFiles (Var1, Var2)
  426.     FOR X! = 1! TO FileCount - 1!
  427.         FOR Y! = X! + 1! TO FileCount
  428.             SELECT CASE Var1
  429.                 CASE 1
  430.                     IF Var2 THEN
  431.                         IF Filenames(X!) > Filenames(Y!) THEN
  432.                             SWAP Filenames(X!), Filenames(Y!)
  433.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  434.                             SWAP FileSize(X!), FileSize(Y!)
  435.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  436.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  437.                         END IF
  438.                     ELSE
  439.                         IF Filenames(X!) < Filenames(Y!) THEN
  440.                             SWAP Filenames(X!), Filenames(Y!)
  441.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  442.                             SWAP FileSize(X!), FileSize(Y!)
  443.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  444.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  445.                         END IF
  446.                     END IF
  447.                 CASE 2
  448.                     IF Var2 THEN
  449.                         IF DateTimeFile(X!) > DateTimeFile(Y!) THEN
  450.                             SWAP Filenames(X!), Filenames(Y!)
  451.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  452.                             SWAP FileSize(X!), FileSize(Y!)
  453.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  454.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  455.                         END IF
  456.                     ELSE
  457.                         IF DateTimeFile(X!) < DateTimeFile(Y!) THEN
  458.                             SWAP Filenames(X!), Filenames(Y!)
  459.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  460.                             SWAP FileSize(X!), FileSize(Y!)
  461.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  462.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  463.                         END IF
  464.                     END IF
  465.                 CASE 3
  466.                     IF Var2 THEN
  467.                         IF FileSize(X!) > FileSize(Y!) THEN
  468.                             SWAP Filenames(X!), Filenames(Y!)
  469.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  470.                             SWAP FileSize(X!), FileSize(Y!)
  471.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  472.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  473.                         END IF
  474.                     ELSE
  475.                         IF FileSize(X!) < FileSize(Y!) THEN
  476.                             SWAP Filenames(X!), Filenames(Y!)
  477.                             SWAP ShortNameFile(X!), ShortNameFile(Y!)
  478.                             SWAP FileSize(X!), FileSize(Y!)
  479.                             SWAP DateTimeFile(X!), DateTimeFile(Y!)
  480.                             SWAP AttributesFile(X!), AttributesFile(Y!)
  481.                         END IF
  482.                     END IF
  483.             END SELECT
  484.         NEXT
  485.     NEXT
  486.     IF Var1 = 3 THEN EXIT SUB
  487.     FOR X! = 1! TO DirCount - 1!
  488.         FOR Y! = X! + 1! TO DirCount
  489.             SELECT CASE Var1
  490.                 CASE 1
  491.                     IF Var2 THEN
  492.                         IF Directories(X!) > Directories(Y!) THEN
  493.                             SWAP Directories(X!), Directories(Y!)
  494.                             SWAP ShortNameDir(X!), ShortNameDir(Y!)
  495.                             SWAP DateTimeDir(X!), DateTimeDir(Y!)
  496.                             SWAP AttributesDir(X!), AttributesDir(Y!)
  497.                         END IF
  498.                     ELSE
  499.                         IF Directories(X!) < Directories(Y!) THEN
  500.                             SWAP Directories(X!), Directories(Y!)
  501.                             SWAP ShortNameDir(X!), ShortNameDir(Y!)
  502.                             SWAP DateTimeDir(X!), DateTimeDir(Y!)
  503.                             SWAP AttributesDir(X!), AttributesDir(Y!)
  504.                         END IF
  505.                     END IF
  506.                 CASE 2
  507.                     IF Var2 THEN
  508.                         IF DateTimeDir(X!) > DateTimeDir(Y!) THEN
  509.                             SWAP Directories(X!), Directories(Y!)
  510.                             SWAP ShortNameDir(X!), ShortNameDir(Y!)
  511.                             SWAP DateTimeDir(X!), DateTimeDir(Y!)
  512.                             SWAP AttributesDir(X!), AttributesDir(Y!)
  513.                         END IF
  514.                     ELSE
  515.                         IF DateTimeDir(X!) < DateTimeDir(Y!) THEN
  516.                             SWAP Directories(X!), Directories(Y!)
  517.                             SWAP ShortNameDir(X!), ShortNameDir(Y!)
  518.                             SWAP DateTimeDir(X!), DateTimeDir(Y!)
  519.                             SWAP AttributesDir(X!), AttributesDir(Y!)
  520.                         END IF
  521.                     END IF
  522.             END SELECT
  523.         NEXT
  524.     NEXT
  525.  
  526. SUB ListFiles
  527.     LineCount = 3
  528.     c = 0
  529.     q = 0
  530.     t = 0
  531.     F! = 0!
  532.     FOR VarQ = 1 TO FileCount
  533.         F! = F! + 1!
  534.         q = -1
  535.         Var% = AttributesFile(VarQ)
  536.         Attr$ = SPACE$(5)
  537.         IF (Var% AND &H20) = &H20 THEN Attrib(VarQ) = "A"
  538.         IF (Var% AND &H4) = &H4 THEN Attrib(VarQ) = "S"
  539.         IF (Var% AND &H2) = &H2 THEN Attrib(VarQ) = "H"
  540.         IF (Var% AND &H1) = &H1 THEN Attrib(VarQ) = "R"
  541.         ' print filesize
  542.         Var# = FileSize(VarQ)
  543.         VarX# = VarX# + Var# ' add bytes
  544.         CALL Suffix(Var#, z$) ' 1,024.0 KB
  545.         z$ = LEFT$(z$, 10)
  546.         z$ = SPACE$(10 - LEN(z$)) + z$ 'suffix
  547.         Size(VarQ) = z$
  548.         ' print longfilename
  549.         z$ = Filenames(VarQ)
  550.         z$ = RTRIM$(z$)
  551.         IF LEN(z$) THEN
  552.             Soubor$(VarQ) = z$
  553.         END IF
  554.     NEXT
  555.     IF q = 0 THEN
  556.         COLOR 14
  557.         PRINT "  No files found."
  558.     END IF
  559.     CALL Suffix(VarX#, z$) ' 1,024.0 KB
  560.  
  561. SUB ListDirs
  562.     LineCount = 3
  563.     c = 0
  564.     q = 0
  565.     t = 0
  566.     F! = 0!
  567.     FOR VarQ = 1 TO DirCount
  568.         F! = F! + 1!
  569.         q = -1
  570.         z$ = ShortNameDir(VarQ)
  571.         z$ = RTRIM$(z$)
  572.         IF z$ = "" THEN
  573.             z$ = Directories(VarQ)
  574.         END IF
  575.         IF LEN(z$) > 12 THEN
  576.             z$ = LEFT$(z$, 12)
  577.         END IF
  578.         Var% = AttributesDir(VarQ)
  579.         Attr$ = SPACE$(5)
  580.         IF (Var% AND &H20) = &H20 THEN Attrib(VarQ) = "A"
  581.         IF (Var% AND &H4) = &H4 THEN Attrib(VarQ) = "S"
  582.         IF (Var% AND &H2) = &H2 THEN Attrib(VarQ) = "H"
  583.         IF (Var% AND &H1) = &H1 THEN Attrib(VarQ) = "R"
  584.  
  585.         z$ = Directories(VarQ)
  586.         z$ = RTRIM$(z$)
  587.         IF LEN(z$) THEN Adresar$(VarQ) = z$
  588.     NEXT
  589.     IF q = 0 THEN Adresar$(0) = "None"
  590.  
  591. ' formats a double numeric string
  592. FUNCTION FormatString$ (s#)
  593.     x$ = ""
  594.     s$ = STR$(s#)
  595.     IF INSTR(s$, "D") THEN ' return string
  596.         FormatString$ = s$
  597.         EXIT FUNCTION
  598.     END IF
  599.     IF LEFT$(s$, 1) = "-" THEN ' store sign
  600.         e$ = "-"
  601.         s$ = MID$(s$, 2)
  602.     END IF
  603.     s$ = LTRIM$(s$) ' format string
  604.     IF INSTR(s$, ".") THEN
  605.         q$ = MID$(s$, INSTR(s$, "."))
  606.         s$ = LEFT$(s$, INSTR(s$, ".") - 1)
  607.     END IF
  608.     FOR l = LEN(s$) TO 3 STEP -3
  609.         x$ = MID$(s$, l - 2, 3) + "," + x$
  610.     NEXT
  611.     IF l > 0 THEN
  612.         x$ = MID$(s$, 1, l) + "," + x$
  613.     END IF
  614.     IF LEN(s$) < 3 THEN
  615.         x$ = s$
  616.     END IF
  617.     IF RIGHT$(x$, 1) = "," THEN
  618.         x$ = LEFT$(x$, LEN(x$) - 1)
  619.     END IF
  620.     x$ = e$ + x$ + q$ ' construct string
  621.     FormatString$ = x$
  622.  
  623. ' calculate byte suffix
  624. SUB Suffix (Var#, Var3$)
  625.     REM B  (Byte) = 00x - 0FFx (hexidecimal zero-based)
  626.     REM KB (Kilobyte) = 1024 B
  627.     REM MB (Megabyte) = 1024 KB (1 MB B)
  628.     REM GB (Gigabyte) = 1024 MB
  629.     REM TB (Terabyte) = 1024 GB (1 MB MB)
  630.     REM PB (Petabyte) = 1024 TB
  631.     REM EB (Exabyte) = 1024 PB (1 MB TB)
  632.  
  633.     ' check double
  634.     VarX# = Var#
  635.     s$ = STR$(VarX#)
  636.     IF INSTR(s$, "D") THEN
  637.         Var3$ = s$
  638.         EXIT SUB
  639.     END IF
  640.  
  641.     ' get sign
  642.     IF VarX# < 0# THEN
  643.         Sign = True
  644.         VarX# = ABS(VarX#)
  645.     END IF
  646.  
  647.     ' calculate bytes
  648.     TempA = False
  649.     DO
  650.         IF VarX# >= 1024 THEN
  651.             VarX# = VarX# / 1024
  652.             TempA = TempA + 1
  653.             IF TempA = 6 THEN
  654.                 EXIT DO
  655.             END IF
  656.         ELSE
  657.             EXIT DO
  658.         END IF
  659.     LOOP
  660.  
  661.     ' calculate byte string
  662.     Var3$ = FormatString$(VarX#)
  663.     IF INSTR(Var3$, ".") THEN
  664.         Var3$ = LEFT$(Var3$, INSTR(Var3$, ".") + 1)
  665.     ELSE
  666.         Var3$ = Var3$ + ".0"
  667.     END IF
  668.  
  669.     ' calculate byte suffix
  670.     Var$ = ""
  671.     IF TempA > 0 THEN
  672.         Var$ = MID$("KMGTPE", TempA, 1)
  673.     END IF
  674.     Var3$ = Var3$ + " " + Var$ + "B"
  675.  
  676.     ' calculate byte sign
  677.     IF Sign THEN
  678.         Var3$ = "-" + Var3$
  679.     END IF
  680.  
  681.  
  682.  
  683.  
  684. SUB MorePrompt (Input.String$, Input.Mask$, Output.String$)
  685.     COLOR White, Black
  686.     PRINT Input.String$ + " ";
  687.     Input.Char$ = Nul
  688.     DO
  689.         LOCATE , , 1
  690.         _LIMIT 100
  691.         Input.Char$ = INKEY$
  692.         IF LEN(Input.Char$) THEN
  693.             Input.Char$ = LCASE$(Input.Char$)
  694.             IF INSTR(Input.Mask$, Input.Char$) THEN
  695.                 PRINT Input.Char$
  696.                 Output.String$ = Input.Char$
  697.                 EXIT DO
  698.             END IF
  699.         END IF
  700.     LOOP
  701.  
  702. ' lists specified drives.
  703. SUB ListDrives (Var$, VarQ)
  704.     ' Var$ = "x..." only list drives in string,
  705.     ' otherwise,
  706.     '   VarQ = 0 list all drives.
  707.     '   VarQ = -1 except A: and B:
  708.     CLS
  709.     l = 0
  710.     FOR c = 1 TO 26
  711.         IF Var$ <> Nul THEN ' display specific drives.
  712.             x$ = UCASE$(Var$)
  713.             IF INSTR(x$, CHR$(c + 64)) THEN
  714.                 x = INSTR(x$, CHR$(c + 64))
  715.                 x = ASC(MID$(x$, x, 1))
  716.                 IF x >= 65 AND x <= 90 THEN
  717.                     x = x - 64
  718.                     IF c = x THEN
  719.  
  720.                         GOSUB DisplayDrive
  721.                     END IF
  722.                 END IF
  723.             END IF
  724.         ELSE
  725.             IF VarQ = 0 THEN ' list all drives
  726.                 GOSUB DisplayDrive
  727.             ELSE
  728.                 ' except A: or B:
  729.                 IF c >= 3 THEN
  730.                     GOSUB DisplayDrive
  731.                 END IF
  732.             END IF
  733.         END IF
  734.         IF h = 20 THEN
  735.             h = 0
  736.             PRINT "-more-";
  737.             DO
  738.                 _LIMIT 50
  739.                 I$ = INKEY$
  740.                 IF LEN(I$) THEN
  741.                     EXIT DO
  742.                 END IF
  743.             LOOP
  744.         END IF
  745.     NEXT
  746.     EXIT SUB
  747.  
  748.     DisplayDrive:
  749.     c$ = CHR$(c + 64)
  750.     Out3 = c$
  751.     IF DRIVEEXISTS(c) = 0 THEN
  752.         h = h + 1
  753.         l = l + 1
  754.         q = -1
  755.         REDIM _PRESERVE Drives(l) AS STRING
  756.         Drives(l) = c$
  757.  
  758.         ' display volume label
  759.         Out3 = c$
  760.         CALL Vlabel(Out3)
  761.         IF RTRIM$(Out3) = Nul THEN
  762.             z$ = DriveType
  763.         ELSE
  764.             z$ = LEFT$(Out3, 12)
  765.         END IF
  766.         z$ = z$ + SPACE$(13 - LEN(z$))
  767.  
  768.         REDIM _PRESERVE DriveLabels(l) AS STRING
  769.         DriveLabels(l) = z$
  770.  
  771.         ' display volume serial number
  772.         Out3 = c$
  773.         CALL Vserial(Out3)
  774.         z$ = LEFT$(Out3, 12)
  775.         z$ = z$ + SPACE$(13 - LEN(z$))
  776.  
  777.         REDIM _PRESERVE DriveSerials(l) AS STRING
  778.         DriveSerials(l) = z$
  779.  
  780.         ' display volume file system type
  781.         Out3 = c$
  782.         CALL Vtype(Out3)
  783.         z$ = LEFT$(Out3, 8)
  784.         z$ = z$ + SPACE$(9 - LEN(z$))
  785.  
  786.         REDIM _PRESERVE DriveType(l) AS STRING
  787.         DriveType(l) = z$
  788.  
  789.         ' display volume total disk space
  790.         COLOR 11, 0
  791.         CALL TotalSpace(Out3)
  792.         x# = INT(VAL(Out3))
  793.         x1# = x#
  794.  
  795.  
  796.         REDIM _PRESERVE DiskTotalSpace(l) AS STRING
  797.         IF x# > 0# THEN
  798.             CALL Suffix(x#, S$) ' 1,024.0 KB
  799.             DiskTotalSpace(l) = S$
  800.         ELSE
  801.             DiskTotalSpace(l) = "<n/a>"
  802.         END IF
  803.  
  804.         ' display volume free disk space
  805.         Out3 = c$
  806.         CALL FreeSpace(Out3)
  807.         y# = INT(VAL(Out3))
  808.         y1# = y#
  809.  
  810.         REDIM _PRESERVE DiskFreeSpace(l) AS STRING
  811.         IF y# > 0# THEN
  812.             CALL Suffix(y#, S$) ' 1,024.0 KB
  813.             DiskFreeSpace(l) = S$
  814.         ELSE
  815.             DiskFreeSpace(l) = "<n/a>"
  816.         END IF
  817.  
  818.         ' display volume used disk space
  819.         REDIM _PRESERVE DiskUsedSpace(l) AS STRING
  820.         IF x1# > 0# OR y1# > 0# THEN
  821.             z# = x1# - y1#
  822.             CALL Suffix(z#, S$) ' 1,024.0 KB
  823.             DiskUsedSpace(l) = S$
  824.         ELSE
  825.             DiskUsedSpace(l) = "<n/a>"
  826.         END IF
  827.     END IF
  828.     RETURN
  829.  
  830.     '    DriveHeader:
  831.     '    h = 2
  832.     '   RETURN
  833.  
  834. ' calculate byte suffix
  835.  
  836. ' formats a double numeric string
  837.  
  838. ' check drive exists.
  839. '  returns -1 if drive not detected.
  840. FUNCTION DRIVEEXISTS (V)
  841.     VarX$ = CHR$(V + 64) + ":\" + CHR$(0)
  842.     VarX = GetDriveType(VarX$)
  843.     DriveType = Nul
  844.     SELECT CASE VarX
  845.         CASE 0
  846.             DriveType = "[UNKNOWN]"
  847.         CASE 1
  848.             DriveType = "[BADROOT]"
  849.         CASE 2
  850.             DriveType = "[REMOVABLE]"
  851.         CASE 3
  852.             DriveType = "[FIXED]"
  853.         CASE 4
  854.             DriveType = "[REMOTE]"
  855.         CASE 5
  856.             DriveType = "[CDROM]"
  857.         CASE 6
  858.             DriveType = "[RAMDISK]"
  859.     END SELECT
  860.     IF VarX > 1 THEN
  861.         DRIVEEXISTS = False
  862.     ELSE
  863.         DRIVEEXISTS = True
  864.     END IF
  865.  
  866. ' get drive freespace
  867. SUB FreeSpace (Var$)
  868.     VarX$ = Var$ + ":\" + CHR$(0)
  869.     Var$ = Nul
  870.     IF DriveType = "[CDROM]" THEN
  871.         EXIT SUB
  872.     END IF
  873.     IF DriveType = "[REMOVABLE]" THEN
  874.         EXIT SUB
  875.     END IF
  876.     r = GetDiskFreeSpaceExA(VarX$, free~&&, total~&&, free2~&&)
  877.     IF r THEN
  878.         Var$ = LTRIM$(STR$(free~&&))
  879.     END IF
  880.     EXIT SUB
  881.  
  882.     r = GetDiskFreeSpaceA(VarX$, sectors&, bytes&, free&, total&)
  883.     IF r THEN
  884.         ' sectors per cluster * bytes per sector * free clusters
  885.         x1# = CDBL(sectors&) * CDBL(bytes&) * CDBL(free&)
  886.         Var$ = LTRIM$(STR$(x1#))
  887.     END IF
  888.  
  889. ' get drive totalspace
  890. SUB TotalSpace (Var$)
  891.     VarX$ = Var$ + ":\" + CHR$(0)
  892.     Var$ = Nul
  893.     IF DriveType = "[CDROM]" THEN
  894.         EXIT SUB
  895.     END IF
  896.     IF DriveType = "[REMOVABLE]" THEN
  897.         EXIT SUB
  898.     END IF
  899.     r = GetDiskFreeSpaceExA(VarX$, free~&&, total~&&, free2~&&)
  900.     IF r THEN
  901.         Var$ = LTRIM$(STR$(total~&&))
  902.     END IF
  903.     EXIT SUB
  904.  
  905.     r = GetDiskFreeSpaceA(VarX$, sectors&, bytes&, free&, total&)
  906.     IF r THEN
  907.         ' sectors per cluster * bytes per sector * total clusters
  908.         x1# = CDBL(sectors&) * CDBL(bytes&) * CDBL(total&)
  909.         Var$ = LTRIM$(STR$(x1#))
  910.     END IF
  911.  
  912. ' get volume label
  913. SUB Vlabel (Var$)
  914.     ' Note: in DOS the volume label was 8.3 format,
  915.     '  however, in windows XP+ it is 32 char.
  916.  
  917.     ' get drive info.
  918.     VarX$ = Var$ + ":\" + CHR$(0)
  919.     Var$ = Nul
  920.     Vname$ = SPACE$(MAX_PATH)
  921.     Fname$ = SPACE$(MAX_PATH)
  922.     R = GetVolumeInformationA(VarX$, Vname$, MAX_PATH, serial~&, empty1~&, empty2~&, Fname$, MAX_PATH)
  923.     IF R THEN
  924.         ' get volume label.
  925.         Var$ = RTRIM$(Vname$)
  926.         v = INSTR(Var$, CHR$(0))
  927.         IF v THEN Var$ = LEFT$(Var$, v - 1)
  928.     END IF
  929.  
  930. ' get volume serial number
  931. SUB Vserial (Var$)
  932.  
  933.     ' get drive info.
  934.     VarX$ = Var$ + ":\" + CHR$(0)
  935.     Var$ = Nul
  936.     Vname$ = SPACE$(MAX_PATH)
  937.     Fname$ = SPACE$(MAX_PATH)
  938.     R = GetVolumeInformationA(VarX$, Vname$, MAX_PATH, serial~&, empty1~&, empty2~&, Fname$, MAX_PATH)
  939.     IF R THEN
  940.         ' serial number.
  941.         Var$ = LEFT$(HEX$(serial~&), 4) + "-" + RIGHT$(HEX$(serial~&), 4)
  942.     END IF
  943.  
  944. ' get volume system type
  945. SUB Vtype (Var$)
  946.  
  947.     ' get drive info.
  948.     VarX$ = Var$ + ":\" + CHR$(0)
  949.     Var$ = Nul
  950.     Vname$ = SPACE$(MAX_PATH)
  951.     Fname$ = SPACE$(MAX_PATH)
  952.     R = GetVolumeInformationA(VarX$, Vname$, MAX_PATH, serial~&, empty1~&, empty2~&, Fname$, MAX_PATH)
  953.     IF R THEN
  954.         ' get volume system type.
  955.         Var$ = RTRIM$(Fname$)
  956.         v = INSTR(Var$, CHR$(0))
  957.         IF v THEN Var$ = LEFT$(Var$, v - 1)
  958.     END IF
  959.  
  960. SUB Filtruj (maska AS STRING) 'prepise FileCount podle predimenzovaneho poctu zanamu do poli FileNames, FileSize, DateTimeFile a ShortNameFile. Zaznamy adresaru zustanou stejne!
  961.     DIM NewFileNames(1) AS STRING 'is for mask using. There was problem if is mask used directly, so this SUB is filtering all records in arrays for correct mask if is used.
  962.     DIM NewFileSize(1) AS DOUBLE
  963.     DIM NewDateTimeFile(1) AS STRING * 19
  964.     DIM NewShortNameFile(1) AS STRING
  965.     DIM NewAttrib(1) AS STRING
  966.     '    new = 1
  967.  
  968.     F$ = RIGHT$(maska$, 4): IF LEFT$(F$, 1) <> "." THEN BEEP: EXIT SUB 'invalid mask
  969.     FOR test = 1 TO FileCount
  970.         FileMask$ = RIGHT$(Filenames(test), 4)
  971.         IF FileMask$ = F$ THEN
  972.             New = New + 1
  973.             REDIM _PRESERVE NewFileNames(New) AS STRING
  974.             REDIM _PRESERVE NewFileSize(New) AS DOUBLE
  975.             REDIM _PRESERVE NewDateTimeFile(New) AS STRING * 19
  976.             REDIM _PRESERVE NewShortNameFile(New) AS STRING
  977.             REDIM _PRESERVE NewAttrib(New) AS STRING
  978.             NewFileNames(New) = Filenames(test)
  979.             NewFileSize(New) = FileSize(test)
  980.             NewDateTimeFile(New) = DateTimeFile(test)
  981.             NewShortNameFile(New) = ShortNameFile(test)
  982.  
  983.             'PRINT UBOUND(attrib), UBOUND(newattrib): SLEEP
  984.             'NewAttrib(New) = Attrib(DirCount + New)
  985.  
  986.         END IF
  987.     NEXT test
  988.     FileCount = New
  989.     REDIM Filenames(1) AS STRING
  990.     REDIM FileSize(1) AS DOUBLE
  991.     REDIM DateTimeFile(1) AS STRING * 19
  992.     REDIM ShortNameFile(1) AS STRING
  993.     '    REDIM Attrib(1) AS STRING
  994.  
  995.     ' REDIM _PRESERVE NewAttrib(UBOUND(newattrib) + DirCount) AS STRING
  996.     '   FOR DirAttrib = 1 TO DirCount
  997.     ' NewAttrib(DirAttrib) = Attrib(DirAttrib)
  998.     ' NEXT
  999.  
  1000.     FOR ReWrite = 1 TO New
  1001.  
  1002.         REDIM _PRESERVE Filenames(ReWrite) AS STRING
  1003.         REDIM _PRESERVE FileSize(ReWrite) AS DOUBLE
  1004.         REDIM _PRESERVE DateTimeFile(ReWrite) AS STRING * 19
  1005.         REDIM _PRESERVE ShortNameFile(ReWrite) AS STRING
  1006.         REDIM _PRESERVE Attrib(DirCount + ReWrite) AS STRING
  1007.  
  1008.         Filenames(ReWrite) = NewFileNames(ReWrite)
  1009.         FileSize(ReWrite) = NewFileSize(ReWrite)
  1010.         DateTimeFile(ReWrite) = NewDateTimeFile(ReWrite)
  1011.         ShortNameFile(ReWrite) = NewShortNameFile(ReWrite)
  1012.         Attrib(ReWrite) = NewAttrib(ReWrite)
  1013.     NEXT ReWrite
  1014.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #6 on: September 15, 2018, 03:47:24 am »
I find original Erik´s source. Maybe it help more, because it is writed more clearly:

Code: QB64: [Select]
  1. REM SOURCE BY EOREDSON!!!
  2.  
  3. REM sample program to get/list/sort lists of filenames/directories v1.0a PD.
  4. ' detect operating system
  5. $IF WIN = 0 THEN
  6.     COLOR 15, 0
  7.     CLS
  8.     PRINT "Sorry, this program only works in Windows.."
  9.     END
  10. CONST MAX_PATH = 260
  11. CONST INVALID_HANDLE_VALUE = -1
  12.  
  13. TYPE FILETIME
  14.     dwLowDateTime AS _UNSIGNED LONG
  15.     dwHighDateTime AS _UNSIGNED LONG
  16.  
  17. TYPE SYSTEMTIME
  18.     wYear AS INTEGER
  19.     wMonth AS INTEGER
  20.     wDayOfWeek AS INTEGER
  21.     wDay AS INTEGER
  22.     wHour AS INTEGER
  23.     wMinute AS INTEGER
  24.     wSecond AS INTEGER
  25.     wMilliseconds AS INTEGER
  26.  
  27. TYPE WIN32_FIND_DATAA
  28.     dwFileAttributes AS _UNSIGNED LONG
  29.     ftCreationTime AS FILETIME
  30.     ftLastAccessTime AS FILETIME
  31.     ftLastWriteTime AS FILETIME
  32.     nFileSizeHigh AS _UNSIGNED LONG
  33.     nFileSizeLow AS _UNSIGNED LONG
  34.     dwReserved0 AS _UNSIGNED LONG
  35.     dwReserved1 AS _UNSIGNED LONG
  36.     cFileName AS STRING * MAX_PATH
  37.     cAlternateFileName AS STRING * 14
  38.  
  39.     FUNCTION FindFirstFileA~%& (BYVAL lpFileName~%&, BYVAL lpFindFileData~%&)
  40.     FUNCTION FindNextFileA& (BYVAL hFindFile~%&, BYVAL lpFindFileData~%&)
  41.     FUNCTION FindClose& (BYVAL hFindFile~%&)
  42.     FUNCTION FileTimeToSystemTime& (lpFileTime AS FILETIME, lpSystemTime AS SYSTEMTIME)
  43.  
  44. DIM SHARED Filenames(1) AS STRING
  45. DIM SHARED Directories(1) AS STRING
  46.  
  47. DIM SHARED FileCount AS SINGLE
  48. DIM SHARED DirCount AS SINGLE
  49.  
  50. DIM SHARED FileSize(1) AS DOUBLE
  51.  
  52. DIM SHARED DateTimeDir(1) AS STRING * 19 ' mm-dd-yyyy hh:mm:ss
  53. DIM SHARED DateTimeFile(1) AS STRING * 19 ' mm-dd-yyyy hh:mm:ss
  54.  
  55. DIM SHARED AttributesDir(1) AS INTEGER
  56. DIM SHARED AttributesFile(1) AS INTEGER
  57.  
  58. DIM SHARED ShortNameDir(1) AS STRING
  59. DIM SHARED ShortNameFile(1) AS STRING
  60.  
  61. DIM SHARED LineCount AS INTEGER
  62.     PRINT "Filespec";
  63.     INPUT Var$
  64.     IF Var$ = "" THEN END
  65.     CALL GetFiles(Var$)
  66.     CALL SortFiles(-1)
  67.     COLOR 14
  68.     PRINT "Dirs:"; DirCount
  69.     PRINT "Files:"; FileCount
  70.     DO
  71.         COLOR 15
  72.         PRINT "Menu"
  73.         PRINT "  (D)irs"
  74.         PRINT "  (F)iles"
  75.         PRINT "  (S)ort"
  76.         PRINT "Option(Q to Quit)";
  77.         LOCATE , , 1
  78.         DO
  79.             _LIMIT 50
  80.             X$ = INKEY$
  81.             IF LEN(X$) THEN
  82.                 SELECT CASE LCASE$(X$)
  83.                     CASE "q"
  84.                         PRINT
  85.                         EXIT DO
  86.                     CASE "d"
  87.                         PRINT
  88.                         CALL ListDirs
  89.                         EXIT DO
  90.                     CASE "f"
  91.                         PRINT
  92.                         CALL ListFiles
  93.                         EXIT DO
  94.                     CASE "s"
  95.                         PRINT
  96.                         COLOR 15
  97.                         PRINT "(A)scending, (D)escending?";
  98.                         DO
  99.                             _LIMIT 50
  100.                             Q$ = INKEY$
  101.                             IF LCASE$(Q$) = "a" THEN
  102.                                 PRINT
  103.                                 CALL SortFiles(-1)
  104.                                 EXIT DO
  105.                             END IF
  106.                             IF LCASE$(Q$) = "d" THEN
  107.                                 PRINT
  108.                                 CALL SortFiles(0)
  109.                                 EXIT DO
  110.                             END IF
  111.                         LOOP
  112.                         LineCount = 25
  113.                         N$ = MorePrompt$
  114.                 END SELECT
  115.             END IF
  116.             IF LEN(Q$) THEN Q$ = "": EXIT DO
  117.             IF LCASE$(X$) = "q" THEN EXIT DO
  118.         LOOP
  119.         IF LCASE$(X$) = "q" THEN EXIT DO
  120.     LOOP
  121.  
  122. SUB GetFiles (Var$)
  123.     DIM Attribute AS INTEGER
  124.     DIM ASCIIZ AS STRING * 260
  125.     DIM finddata AS WIN32_FIND_DATAA
  126.     DIM Wfile.Handle AS _UNSIGNED _OFFSET
  127.     DIM SysTime AS SYSTEMTIME
  128.  
  129.     DirCount = 0!
  130.     FileCount = 0!
  131.     ASCIIZ = Var$ + CHR$(0)
  132.     Wfile.Handle = FindFirstFileA(_OFFSET(ASCIIZ), _OFFSET(finddata))
  133.     IF Wfile.Handle <> INVALID_HANDLE_VALUE THEN
  134.         DO
  135.             Attribute = finddata.dwFileAttributes
  136.             Filename$ = finddata.cFileName
  137.             Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  138.             IF Filename$ <> "." AND Filename$ <> ".." THEN
  139.  
  140.                 ' store date/time
  141.                 x& = FileTimeToSystemTime&(finddata.ftLastWriteTime, SysTime)
  142.                 Var$ = RIGHT$("00" + LTRIM$(STR$(SysTime.wMonth)), 2) + "-"
  143.                 Var$ = Var$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wDay)), 2) + "-"
  144.                 Var$ = Var$ + LTRIM$(STR$(SysTime.wYear)) + " "
  145.                 Var$ = Var$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wMonth)), 2) + "-"
  146.                 Var$ = Var$ + RIGHT$("00" + LTRIM$(STR$(SysTime.wDay)), 2) + "-"
  147.                 Var$ = Var$ + LTRIM$(STR$(SysTime.wYear))
  148.  
  149.                 IF (Attribute AND &H10) = &H10 THEN
  150.                     DirCount = DirCount + 1!
  151.                     REDIM _PRESERVE Directories(DirCount) AS STRING
  152.                     Directories(DirCount) = Filename$
  153.  
  154.                     REDIM _PRESERVE DateTimeDir(DirCount) AS STRING * 19
  155.                     DateTimeDir(DirCount) = Var$
  156.  
  157.                     REDIM _PRESERVE AttributesDir(DirCount) AS INTEGER
  158.                     AttributesDir(DirCount) = Attribute
  159.  
  160.                     Filename$ = finddata.cAlternateFileName
  161.                     Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  162.                     REDIM _PRESERVE ShortNameDir(DirCount) AS STRING
  163.                     ShortNameDir(DirCount) = Filename$
  164.                 ELSE
  165.                     FileCount = FileCount + 1!
  166.                     REDIM _PRESERVE Filenames(FileCount) AS STRING
  167.                     Filenames(FileCount) = Filename$
  168.                     REDIM _PRESERVE FileSize(FileCount) AS DOUBLE
  169.                     F# = finddata.nFileSizeHigh * &H100000000~&& OR finddata.nFileSizeLow
  170.                     FileSize(FileCount) = F#
  171.  
  172.                     REDIM _PRESERVE DateTimeFile(FileCount) AS STRING * 19
  173.                     DateTimeFile(FileCount) = Var$
  174.  
  175.                     REDIM _PRESERVE AttributesFile(FileCount) AS INTEGER
  176.                     AttributesFile(FileCount) = Attribute
  177.  
  178.                     Filename$ = finddata.cAlternateFileName
  179.                     Filename$ = LEFT$(Filename$, INSTR(Filename$, CHR$(0)) - 1)
  180.                     REDIM _PRESERVE ShortNameFile(FileCount) AS STRING
  181.                     ShortNameFile(FileCount) = Filename$
  182.                 END IF
  183.             END IF
  184.         LOOP WHILE FindNextFileA(Wfile.Handle, _OFFSET(finddata))
  185.         x = FindClose(Wfile.Handle)
  186.     END IF
  187.  
  188. SUB SortFiles (Var) ' Var=-1 ascending
  189.     FOR X! = 1! TO DirCount
  190.         FOR Y! = X! + 1! TO DirCount
  191.             IF Var THEN
  192.                 IF Directories(X!) > Directories(Y!) THEN
  193.                     SWAP Directories(X!), Directories(Y!)
  194.                     SWAP ShortNameDir(X!), ShortNameDir(Y!)
  195.                     SWAP DateTimeDir(X!), DateTimeDir(Y!)
  196.                     SWAP AttributesDir(X!), AttributesDir(Y!)
  197.                 END IF
  198.             ELSE
  199.                 IF Directories(X!) < Directories(Y!) THEN
  200.                     SWAP Directories(X!), Directories(Y!)
  201.                     SWAP ShortNameDir(X!), ShortNameDir(Y!)
  202.                     SWAP DateTimeDir(X!), DateTimeDir(Y!)
  203.                     SWAP AttributesDir(X!), AttributesDir(Y!)
  204.                 END IF
  205.             END IF
  206.         NEXT
  207.     NEXT
  208.     FOR X! = 1! TO FileCount
  209.         FOR Y! = X! + 1! TO FileCount
  210.             IF Var THEN
  211.                 IF Filenames(X!) > Filenames(Y!) THEN
  212.                     SWAP Filenames(X!), Filenames(Y!)
  213.                     SWAP ShortNameFile(X!), ShortNameFile(Y!)
  214.                     SWAP FileSize(X!), FileSize(Y!)
  215.                     SWAP DateTimeFile(X!), DateTimeFile(Y!)
  216.                     SWAP AttributesFile(X!), AttributesFile(Y!)
  217.                 END IF
  218.             ELSE
  219.                 IF Filenames(X!) < Filenames(Y!) THEN
  220.                     SWAP Filenames(X!), Filenames(Y!)
  221.                     SWAP ShortNameFile(X!), ShortNameFile(Y!)
  222.                     SWAP FileSize(X!), FileSize(Y!)
  223.                     SWAP DateTimeFile(X!), DateTimeFile(Y!)
  224.                     SWAP AttributesFile(X!), AttributesFile(Y!)
  225.                 END IF
  226.             END IF
  227.         NEXT
  228.     NEXT
  229.  
  230. FUNCTION MorePrompt$
  231.     LineCount = LineCount + 1
  232.     IF LineCount >= 24 THEN
  233.         LineCount = 2
  234.         COLOR 15
  235.         PRINT "-more-";
  236.         DO
  237.             _LIMIT 50
  238.             X$ = INKEY$
  239.             IF LEN(X$) THEN
  240.                 PRINT
  241.                 MorePrompt$ = LCASE$(X$)
  242.                 EXIT FUNCTION
  243.             END IF
  244.         LOOP
  245.     END IF
  246.  
  247. SUB ListFiles
  248.  
  249.     ' display header
  250.     COLOR 15
  251.     GOSUB TitleHeader
  252.  
  253.     LineCount = 3
  254.     c = 0
  255.     q = 0
  256.     t = 0
  257.     f! = 0!
  258.     FOR VarQ = 1 TO FileCount
  259.         f! = f! + 1!
  260.         q = -1
  261.         IF t THEN
  262.             t = 0
  263.             GOSUB TitleHeader
  264.         END IF
  265.  
  266.         ' print shortfilename
  267.         z$ = ShortNameFile(VarQ)
  268.         z$ = RTRIM$(z$)
  269.         IF z$ = "" THEN
  270.             z$ = Filenames(VarQ)
  271.         END IF
  272.         IF LEN(z$) > 12 THEN
  273.             z$ = LEFT$(z$, 12)
  274.         END IF
  275.         COLOR 14
  276.         PRINT UCASE$(z$);
  277.         IF LEN(z$) <= 14 THEN
  278.             PRINT SPACE$(14 - LEN(z$));
  279.         END IF
  280.  
  281.         ' print date/time
  282.         COLOR 10
  283.         PRINT DateTimeFile(VarQ);
  284.  
  285.         ' attributes of filename
  286.         Var% = AttributesFile(VarQ)
  287.         Attr$ = SPACE$(5)
  288.         IF (Var% AND &H20) = &H20 THEN
  289.             MID$(Attr$, 1, 1) = "A" ' archive
  290.         END IF
  291.         IF (Var% AND &H4) = &H4 THEN
  292.             MID$(Attr$, 3, 1) = "S" ' system
  293.         END IF
  294.         IF (Var% AND &H2) = &H2 THEN
  295.             MID$(Attr$, 4, 1) = "H" ' hidden
  296.         END IF
  297.         IF (Var% AND &H1) = &H1 THEN
  298.             MID$(Attr$, 5, 1) = "R" ' read-only
  299.         END IF
  300.         COLOR 12
  301.         PRINT "  "; Attr$; " ";
  302.  
  303.         ' print filesize
  304.         Var# = FileSize(VarQ)
  305.         VarX# = VarX# + Var# ' add bytes
  306.         CALL Suffix(Var#, z$) ' 1,024.0 KB
  307.         z$ = LEFT$(z$, 10)
  308.         z$ = SPACE$(10 - LEN(z$)) + z$
  309.         COLOR 11
  310.         PRINT z$; " ";
  311.  
  312.         ' print longfilename
  313.         z$ = Filenames(VarQ)
  314.         z$ = RTRIM$(z$)
  315.         IF LEN(z$) THEN
  316.             IF LEN(z$) > 25 THEN
  317.                 z$ = LEFT$(z$, 24) + "..."
  318.             END IF
  319.             COLOR 14
  320.             PRINT z$;
  321.         END IF
  322.         PRINT
  323.         IF MorePrompt$ = "n" THEN
  324.             EXIT FOR
  325.         END IF
  326.     NEXT
  327.     IF q = 0 THEN
  328.         COLOR 14
  329.         PRINT "No files found."
  330.     END IF
  331.  
  332.     ' print totals
  333.     COLOR 15
  334.     PRINT "------------                             ----------"
  335.     TotalLine$ = "Files " + FormatString$(CDBL(f!))
  336.     TotalLine$ = LEFT$(TotalLine$, 40)
  337.     TotalLine$ = TotalLine$ + SPACE$(40 - LEN(TotalLine$))
  338.  
  339.     CALL Suffix(VarX#, z$) ' 1,024.0 KB
  340.     TotalLine$ = TotalLine$ + SPACE$(11 - LEN(z$)) + z$
  341.     PRINT TotalLine$
  342.     EXIT SUB
  343.  
  344.     TitleHeader:
  345.     COLOR 15
  346.     PRINT "Filename      Date        Time     Attr        Size Longfilename"
  347.     PRINT "------------  ----------  -------- ----- ---------- ------------"
  348.     RETURN
  349.  
  350. SUB ListDirs
  351.  
  352.     ' display header
  353.     COLOR 15
  354.     GOSUB TitleHeader
  355.  
  356.     LineCount = 3
  357.     c = 0
  358.     q = 0
  359.     t = 0
  360.     f! = 0!
  361.     FOR VarQ = 1 TO DirCount
  362.         f! = f! + 1!
  363.         q = -1
  364.         IF t THEN
  365.             t = 0
  366.             GOSUB TitleHeader
  367.         END IF
  368.  
  369.         ' print shortfilename
  370.         z$ = ShortNameDir(VarQ)
  371.         z$ = RTRIM$(z$)
  372.         IF z$ = "" THEN
  373.             z$ = Directories(VarQ)
  374.         END IF
  375.         IF LEN(z$) > 12 THEN
  376.             z$ = LEFT$(z$, 12)
  377.         END IF
  378.         COLOR 14
  379.         PRINT UCASE$(z$);
  380.         IF LEN(z$) <= 14 THEN
  381.             PRINT SPACE$(14 - LEN(z$));
  382.         END IF
  383.  
  384.         ' print date/time
  385.         COLOR 10
  386.         PRINT DateTimeDir(VarQ);
  387.  
  388.         ' attributes of filename
  389.         Var% = AttributesDir(VarQ)
  390.         Attr$ = SPACE$(5)
  391.         IF (Var% AND &H20) = &H20 THEN
  392.             MID$(Attr$, 1, 1) = "A" ' archive
  393.         END IF
  394.         IF (Var% AND &H4) = &H4 THEN
  395.             MID$(Attr$, 3, 1) = "S" ' system
  396.         END IF
  397.         IF (Var% AND &H2) = &H2 THEN
  398.             MID$(Attr$, 4, 1) = "H" ' hidden
  399.         END IF
  400.         IF (Var% AND &H1) = &H1 THEN
  401.             MID$(Attr$, 5, 1) = "R" ' read-only
  402.         END IF
  403.         COLOR 12
  404.         PRINT "  "; Attr$; " ";
  405.  
  406.         ' print longfilename
  407.         z$ = Directories(VarQ)
  408.         z$ = RTRIM$(z$)
  409.         IF LEN(z$) THEN
  410.             IF LEN(z$) > 35 THEN
  411.                 z$ = LEFT$(z$, 34) + "..."
  412.             END IF
  413.             COLOR 14
  414.             PRINT z$;
  415.         END IF
  416.         PRINT
  417.         IF MorePrompt$ = "n" THEN
  418.             EXIT FOR
  419.         END IF
  420.     NEXT
  421.     IF q = 0 THEN
  422.         COLOR 14
  423.         PRINT "No dirs found."
  424.     END IF
  425.  
  426.     ' print totals
  427.     COLOR 15
  428.     PRINT "------------"
  429.     TotalLine$ = "Dirs " + FormatString$(CDBL(f!))
  430.     PRINT TotalLine$
  431.     EXIT SUB
  432.  
  433.     TitleHeader:
  434.     COLOR 15
  435.     PRINT "Filename      Date        Time     Attr  Longfilename"
  436.     PRINT "------------  ----------  -------- ----- ------------"
  437.     RETURN
  438.  
  439. ' formats a double numeric string
  440. FUNCTION FormatString$ (s#)
  441.     x$ = ""
  442.     s$ = STR$(s#)
  443.     IF INSTR(s$, "D") THEN ' return string
  444.         FormatString$ = s$
  445.         EXIT FUNCTION
  446.     END IF
  447.     IF LEFT$(s$, 1) = "-" THEN ' store sign
  448.         e$ = "-"
  449.         s$ = MID$(s$, 2)
  450.     END IF
  451.     s$ = LTRIM$(s$) ' format string
  452.     IF INSTR(s$, ".") THEN
  453.         q$ = MID$(s$, INSTR(s$, "."))
  454.         s$ = LEFT$(s$, INSTR(s$, ".") - 1)
  455.     END IF
  456.     FOR l = LEN(s$) TO 3 STEP -3
  457.         x$ = MID$(s$, l - 2, 3) + "," + x$
  458.     NEXT
  459.     IF l > 0 THEN
  460.         x$ = MID$(s$, 1, l) + "," + x$
  461.     END IF
  462.     IF LEN(s$) < 3 THEN
  463.         x$ = s$
  464.     END IF
  465.     IF RIGHT$(x$, 1) = "," THEN
  466.         x$ = LEFT$(x$, LEN(x$) - 1)
  467.     END IF
  468.     x$ = e$ + x$ + q$ ' construct string
  469.     FormatString$ = x$
  470.  
  471. ' calculate byte suffix
  472. SUB Suffix (Var#, Var3$)
  473.     REM B  (Byte) = 00x - 0FFx (hexidecimal zero-based)
  474.     REM KB (Kilobyte) = 1024 B
  475.     REM MB (Megabyte) = 1024 KB (1 MB B)
  476.     REM GB (Gigabyte) = 1024 MB
  477.     REM TB (Terabyte) = 1024 GB (1 MB MB)
  478.     REM PB (Petabyte) = 1024 TB
  479.     REM EB (Exabyte) = 1024 PB (1 MB TB)
  480.  
  481.     ' check double
  482.     VarX# = Var#
  483.     s$ = STR$(VarX#)
  484.     IF INSTR(s$, "D") THEN
  485.         Var3$ = s$
  486.         EXIT SUB
  487.     END IF
  488.  
  489.     ' get sign
  490.     IF VarX# < 0# THEN
  491.         Sign = True
  492.         VarX# = ABS(VarX#)
  493.     END IF
  494.  
  495.     ' calculate bytes
  496.     TempA = False
  497.     DO
  498.         IF VarX# >= 1024 THEN
  499.             VarX# = VarX# / 1024
  500.             TempA = TempA + 1
  501.             IF TempA = 6 THEN
  502.                 EXIT DO
  503.             END IF
  504.         ELSE
  505.             EXIT DO
  506.         END IF
  507.     LOOP
  508.  
  509.     ' calculate byte string
  510.     Var3$ = FormatString$(VarX#)
  511.     IF INSTR(Var3$, ".") THEN
  512.         Var3$ = LEFT$(Var3$, INSTR(Var3$, ".") + 1)
  513.     ELSE
  514.         Var3$ = Var3$ + ".0"
  515.     END IF
  516.  
  517.     ' calculate byte suffix
  518.     Var$ = ""
  519.     IF TempA > 0 THEN
  520.         Var$ = MID$("KMGTPE", TempA, 1)
  521.     END IF
  522.     Var3$ = Var3$ + " " + Var$ + "B"
  523.  
  524.     ' calculate byte sign
  525.     IF Sign THEN
  526.         Var3$ = "-" + Var3$
  527.     END IF
  528.  

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #7 on: September 15, 2018, 12:54:53 pm »
Or Trim it outside of the loop if they're DIM AS STRING.
FOR I = 1 TO LIMIT
    FFiles(I).NameL = RTRIM$(FFiles(I).NameL)
NEXT
Then do the IFs and all.

Unfortuantly they are fixed length strings inside a TYPE.
I was going to break it down into a dozen DIMs cause the memory issue with large arrays i was having but your example in that post
DIM m AS _MEM, sz AS _INTEGER64
DO
    sz = sz + 10000000 '10 million bytes at a time
    PRINT sz
    m = _MEMNEW(sz) 'reserve a data space of proper size
    _MEMFREE m
LOOP
gave me the idea to try an use MEM to get it done, which works.(which my machine allowed 2 150 000 000 using MEM)
It would take quite a bit of recoding at this point to go back and DIM each element. now if we could use variable length strings in types that would change things but ,like arrays in type, that will never happen.

File omission would mean having a program that is not 100 percent. So I'll ask about the nature of the problem. How do you get a list of files on a disk? Are you using Linux and / or Windows?

true, but I'm willing to accept a certain % of error(in missed duplicates), and as there are only about 400 files with such characters its not really worth recoding a large portion to fix, I was just wondering if there was a simple solution I had missed, thought about bout using DIR and having it generate the 12 character file names too, thats how I accomplished this back in QB45. Didn't realize QB64 would need to go that route too. but thanks anyway, If I decide to revisit this endeavor in the future I'll keep that code in mind.
Granted after becoming radioactive I only have a half-life!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #8 on: September 15, 2018, 01:24:31 pm »
Okay, but Erik's program will return both types of fields, so 8.3 and long name. I think the adjustment should not be too drastic :-D

Offline PMACKAY

  • Forum Regular
  • Posts: 188
  • LIFE is Temporary
    • View Profile
Re: What to do about non ASCII characters in file names?
« Reply #9 on: September 16, 2018, 08:19:56 am »
_CONTROLCHR OFF 


NOT SURE BUT WONDER IF THE BOVE WILL WORK
MackyWhite

FellippeHeitor

  • Guest
Re: What to do about non ASCII characters in file names?
« Reply #10 on: September 16, 2018, 08:27:12 am »
Not the same functionality. What _CONTROLCHR OFF does is prevent low ascii characters from performing as they usually do in terminals, like CHR$(10) creating a new line, CHR$(9) moving the cursor ahead etc.