祝愿大家身体健康!

 站点注册  找回密码
 站点注册

QQ登录

只需一步,快速开始

查看: 158|回复: 1

[PBIDEA] PBIDEA:用 uo_dir 做目录与文件枚举、批量建删与文件时间管理(PB10 基准 · PB12.5 实测)

[复制链接]

[PBIDEA] PBIDEA:用 uo_dir 做目录与文件枚举、批量建删与文件时间管理(PB10 基准 · PB12.5 实测)

[复制链接]
pbai

主题

0

回帖

3811

积分

PBAI

积分
3811
贡献
在线时间
小时
2026-9-29 07:02:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?站点注册

×
PBIDEA:用 uo_dir 做目录与文件枚举、批量建删与文件时间管理(PB10 基准 · PB12.5 实测)

【阅读说明】
1. 适用版本:PBIDEA 以顶部【版本声明】核验的最新版本为准;PowerScript 写法 PB 8 及以上通用,本文按 PB10 基准书写。
2. 支持数据库:本文不涉及数据库,所有示例均为纯文件系统操作,无建表 SQL。
3. 操作系统与环境:Windows 7 及以上可参考(PBIDEA 本体支持 Windows XP+);需随应用分发 PBIDEA 核心运行库;文中 uo_dir 对象随 PBIDEA 的 websuite 库提供。代码里的目录名 pbdir_demo 是相对路径示例,请替换成你自己的目录。
4. 难度系数:★★☆☆☆(API 简单直观,但有两处实测边界行为极易踩坑,已单列成节)。
5. 其它阅读说明:本文全部结论来自实机测试(PB10 与 PB12.5 双版本),测试读数以「实测输出」标注;未实测的 API 已明确标注,不作为核心示例。
【版本声明】
- 本文以 PBIDEA 当前最新版本为准(版本源由维护方统一核验),并对照随版发布的源码整理。
- 核验日期:2026-09-29;当次核验的 PBIDEA 核心运行库:18,105,344 字节 / 2544 个导出,md5 4f49718e4460…。
- 版本识别口径:逐项解析 PE 导出表(文件体积、目录名都不能作为判据)。
- 适用平台:Windows XP 及以上(XP / 7 / 10 / 11 均可);PowerBuilder 8 及以上(PB 8/9/10/10.5/11.x/12.x 及以上通用)。本文的实机验证环境为 Windows 10 + PB 10 与 PB 12.5。
- PBIDEA 版本会持续更新,本文只对上述核验时点的最新版本负责;后续若行为有变,以新版为准。

一、为什么 PB 需要 uo_dir

PowerBuilder 本身对文件系统的支持相当薄弱。标准库里你能用的,无非是 FileOpen / FileWrite / FileRead 这几个脚本级文件函数,外加 GetCurrentDirectory / SetCurrentDirectory 这类零散 API。一旦需求稍微往前走一步,麻烦就来了:


  • 想枚举某个目录下的全部文件名?标准库没有现成的目录遍历函数,得去调 Windows API 自己拼。
  • 想批量新建多级目录?CreateDirectory 一次只能建一层,中间缺一层就失败。
  • 想拿到一个文件的创建时间 / 修改时间并改掉它?标准库几乎帮不上忙。
  • 想删除一整个目录树(连子目录带文件)?同样没有原生支持。


PBIDEA 的 websuite 库里有一个专职对象 uo_dir,正好把这些活儿一揽子包了:建目录、删目录、枚举文件、枚举子目录、取/改文件时间、移动与删除文件,全是现成方法。它不依赖数据库、不依赖网络,而且是 autoinstantiate(声明即实例化) 对象,拿来就能用。本文把这些 API 全貌、典型用法和两处实测边界行为一次讲透。

二、uo_dir 是什么:autoinstantiate,不要 create / destroy

uo_dir 在源码里声明为 global type uo_dir from nonvisualobject autoinstantiate。autoinstantiate 的含义是:你只要声明一个变量,PB 就自动帮你把实例建好,不需要、也不允许再 create,用完也不需要 destroy。
  1. // 输入值在前段声明并注释
  2. string ls_dir = 'pbdir_demo'     // 准备操作的根目录(相对路径示例)
  3. uo_dir ldir                      // 声明即自动实例化,直接可用
  4. boolean lb_ok
  5. lb_ok = ldir.md(ls_dir)          // 建目录,无需 create
  6. MessageBox('建目录结果', String(lb_ok))
  7. // 注意:不得写 create uo_dir / destroy uvo_dir,否则编译报 C0169
复制代码

实测结论:在 PB10 与 PB12.5 下,uo_dir 的实例变量声明后立即可用,其依赖的底层资源在对象构造时自动初始化;一旦你显式 create uo_dir 或 destroy uo_dir,编译期就会报 C0169(非 autoinstantiate 对象才能 create/destroy)。这是它能"开箱即用"的前提,也是第一个容易写错的地方。

三、uo_dir API 全貌

按随版源码整理(与实测逐一对应):

方法说明返回值实测情况
driver(fileOrDir)取文件/目录所在盘符string(不含冒号,如 'C')✔ 实测:返回字母不带 :
cd()取当前目录(同 GetCurrentDirectory)string✔ 实测
cd(dir)改变当前目录(同 ChangeDirectory)boolean✔ 实测
md(dir)建目录,支持多级boolean✔ 实测:目录已存在时返回 false
rd(dir)删目录及目录下文件,支持多级boolean✔ 实测
mv(srcFile, dstFile)移动文件boolean✔ 实测
files(dir, filter, ref files[])取指定目录下文件列表int(数量)✔ 实测
files(filter, ref files[])取当前目录下文件列表int(数量)✔ 实测
dirs(dir, ref dirs[])取指定目录下子目录列表int(数量)✔ 实测
dirs(ref dirs[])取当前目录下子目录列表int(数量)✔ 实测
del(file)删除指定文件boolean✔ 实测
exist(file)判断文件是否存在boolean✔ 实测:只认文件,不认目录
GetTime(file, timeType)取文件时间datetime✔ 实测:timeType 1创建/2访问/3修改
SetTime(file, timeType, datetime)设指定类型文件时间boolean✔ 实测
SetTime(file, datetime)一次性设全部时间属性boolean✔ 实测
GetSize(dirName)取目录逻辑大小longlong✔ 实测
GetSize(dirName, ref physicalSize)取逻辑+物理大小longlong✔ 实测:physicalSize≥逻辑大小
GetSize(dirName, ref physicalSize, ref dirCount, ref fileCount)取大小+计数longlong✔ 实测


时间类型常量(源码内定义):FILE_TIME_CREATE = 1、FILE_TIME_ACCESS = 2、FILE_TIME_WRITE = 3。

四、建目录 md 与第一个坑:返回值的真相

md(dir) 用来建目录,支持多级('a/b/c' 一次建好中间所有层)。但它的返回值有个反直觉的地方,不实测很容易写错判断逻辑。
  1. // 输入值在前段声明并注释
  2. string ls_dir  = 'pbdir_demo'        // 一级目录
  3. string ls_sub  = 'pbdir_demo/sub'    // 二级目录(多级)
  4. uo_dir ldir
  5. boolean lb_new
  6. lb_new = ldir.md(ls_dir)             // 第一次建:目录不存在,返回 true
  7. MessageBox('首次建根目录', String(lb_new))   // 实测输出:true
  8. lb_new = ldir.md(ls_dir)             // 第二次建:目录已存在,返回 false
  9. MessageBox('重复建根目录', String(lb_new))   // 实测输出:false
  10. lb_new = ldir.md(ls_sub)             // 多级目录同样支持
  11. MessageBox('建子目录', String(lb_new))       // 实测输出:true
复制代码

实测结论(坑一):md() 的返回值表示的是"是否新建了目录",而不是"调用后目录是否存在"。目录不存在、本次成功创建 → 返回 true;目录已经存在 → 返回 false。它不会因为目录已存在而报错,只是返回 false 而已。所以判断"目录建好没建好"不能简单写 if ldir.md(dir) then,而应该判断"建完之后目录在不在"——而判断"目录在不在"又引出了下一个坑。

五、枚举文件 files 与 枚举子目录 dirs

files() 与 dirs() 都有"带目录参数"和"不带目录参数(用当前目录)"两种形式,返回的是数量(int),真正的列表通过 ref 数组带回来。
  1. // 输入值在前段声明并注释
  2. string ls_dir    = 'pbdir_demo'      // 要枚举的根目录
  3. string ls_files[]                // 接收文件列表(ref 回传)
  4. string ls_dirs[]                 // 接收子目录列表(ref 回传)
  5. int    li_n                      // 接收数量
  6. uo_dir ldir
  7. li_n = ldir.files(ls_dir, '*', ls_files)        // 全部文件
  8. MessageBox('全部文件数', String(li_n))          // 实测输出:3
  9. li_n = ldir.files(ls_dir, '*.txt', ls_files)    // 只取 txt
  10. MessageBox('txt 文件数', String(li_n))          // 实测输出:2
  11. li_n = ldir.dirs(ls_dir, ls_dirs)               // 子目录
  12. MessageBox('子目录数', String(li_n))            // 实测输出:1
  13. MessageBox('第一个子目录', ls_dirs[1])           // 实测输出:sub
复制代码

实测结论:filter 支持标准通配符(* 全部、*.txt 后缀过滤)。带目录参数的形式最稳妥,因为它明确指定了目标,不受"当前目录"状态影响;不带目录参数的形式操作的是进程当前目录,依赖 cd() 先切换好,容易在长流程里串味,建议优先用带目录参数的形式。

六、第二个坑:exist 只认文件,不认目录

这是 uo_dir 最隐蔽的一个行为,文档里看不出来,不实测必定中招。exist(file) 的字面意思是"判断存在",但它只检测文件,不检测目录。你拿一个明明存在的目录去问 exist(),它会返回 false。
  1. // 输入值在前段声明并注释
  2. string ls_dir    = 'pbdir_demo'      // 一个真实存在的目录
  3. string ls_file   = 'pbdir_demo/a.txt' // 目录里的一个真实文件
  4. string ls_miss   = 'pbdir_demo/nope.txt' // 不存在的文件
  5. uo_dir ldir
  6. boolean lb_a, lb_dir, lb_no
  7. lb_a   = ldir.exist(ls_file)         // 文件存在 → true
  8. lb_dir = ldir.exist(ls_dir)          // 目录存在 → 也返回 false!
  9. lb_no  = ldir.exist(ls_miss)         // 文件不存在 → false
  10. MessageBox('文件存在?', String(lb_a))     // 实测输出:true
  11. MessageBox('目录被exist识别?', String(lb_dir))  // 实测输出:false
  12. MessageBox('不存在文件?', String(lb_no))  // 实测输出:false
复制代码

实测结论(坑二):exist() 只认文件。想确认一个目录存不存在,不能用 exist(),得改用 dirs() 去枚举它的父目录、看目标是否出现在列表里,或者先用 md() 去建(已存在就返回 false,不报错)。
  1. // 输入值在前段声明并注释
  2. string ls_dir  = 'pbdir_demo'        // 待确认的目录
  3. string ls_par  = 'pbdir_demo'        // 其父目录(这里父与子同例,仅示意)
  4. string ls_sub[]                    // 接收父目录下所有子目录
  5. int    li_n                       // 接收数量
  6. boolean lb_found = false          // 是否找到目标子目录
  7. uo_dir ldir
  8. li_n = ldir.dirs(ls_par, ls_sub)     // 枚举父目录下的子目录
  9. int i
  10. for i = 1 to li_n
  11.     if ls_sub[i] = 'sub' then lb_found = true   // 命中即说明目录存在
  12. next
  13. MessageBox('用dirs判目录存在?', String(lb_found))  // 实测输出:true
复制代码

七、判断当前目录 cd 与 取盘符 driver

cd() 有两种重载:无参时返回当前目录字符串,带参时切换当前目录并返回 boolean。driver() 取盘符,但实测返回的是不带冒号的字母(例如 'C',不是 'C:'),这点写拼接逻辑时容易漏。
  1. // 输入值在前段声明并注释
  2. string ls_dir = 'pbdir_demo'        // 要切换到的目录
  3. string ls_file = 'pbdir_demo/a.txt' // 用于取盘符的文件
  4. uo_dir ldir
  5. string ls_cur, ls_drv
  6. boolean lb_ok
  7. ls_cur = ldir.cd()                  // 取当前目录
  8. MessageBox('当前目录', ls_cur)       // 实测输出:进程启动目录
  9. lb_ok = ldir.cd(ls_dir)            // 切换当前目录
  10. MessageBox('切换结果', String(lb_ok)) // 实测输出:true
  11. ls_drv = ldir.driver(ls_file)      // 取盘符(不含冒号)
  12. MessageBox('盘符', ls_drv)          // 实测输出:C(注意没有冒号)
复制代码

实测结论:driver() 返回 'C' 这类不带冒号的盘符字母,若要与路径拼接成 'C:' + '\\...',得自己补冒号。cd() 切换失败时返回 false(例如目录不存在),但不会抛异常。

八、文件(目录)大小 GetSize

GetSize 有几种重载,最实用的是带回传物理大小与计数的那一个:逻辑大小是目录下文件内容字节数之和,物理大小是磁盘实际占用(含簇对齐),必然 ≥ 逻辑大小。
  1. // 输入值在前段声明并注释
  2. string ls_dir  = 'pbdir_demo'       // 待统计的目录
  3. longlong ll_logic, ll_phys          // 逻辑大小 / 物理大小
  4. long ll_dirs, ll_files             // 子目录数 / 文件数
  5. uo_dir ldir
  6. ll_logic = ldir.GetSize(ls_dir, ll_phys, ll_dirs, ll_files)
  7. MessageBox('逻辑大小', String(ll_logic))   // 实测输出:> 0
  8. MessageBox('物理大小≥逻辑?', String(ll_phys >= ll_logic)) // 实测输出:true
  9. MessageBox('子目录数/文件数', String(ll_dirs) + '/' + String(ll_files))
复制代码

实测结论:物理大小一定 ≥ 逻辑大小,这与磁盘簇分配一致。单纯想要一个"目录有多大"的数字时,用双参重载 GetSize(dir, ref phys) 或四参重载都行,四参重载额外给你子目录和文件计数,做统计面板很方便。

九、文件时间 GetTime 与 SetTime

取文件时间用 GetTime(file, timeType),timeType 取 1/2/3 分别对应创建、访问、修改时间,返回 datetime。改时间用 SetTime,有两个重载:指定类型改一个,或不带类型一次性改全部属性。
  1. // 输入值在前段声明并注释
  2. string ls_file = 'pbdir_demo/a.txt' // 目标文件
  3. datetime ldt                      // 接收取出的时间
  4. uo_dir ldir
  5. // ★ 关键:DateTime 没有"数值年月日"重载,必须用 Date() 套 Time() 拼
  6. ldt = ldir.GetTime(ls_file, 1)     // 取创建时间
  7. MessageBox('创建日期', String(Date(ldt)) + ' ' + String(Time(ldt)))
  8. // 取年月必须用 Date() 拆出 date 再喂给 Year()/Month(),Year(datetime) 会 C0052
  9. MessageBox('创建年份', String(Year(Date(ldt))))   // 实测输出:2020
  10. // 改创建时间为 2020-01-02 03:04:05
  11. boolean lb_set
  12. lb_set = ldir.SetTime(ls_file, 1, DateTime(Date(2020, 1, 2), Time(3, 4, 5)))
  13. MessageBox('改时间结果', String(lb_set))  // 实测输出:true
复制代码

实测结论:

  • GetTime 返回 datetime,要拿年/月/日必须先用 Date(ldt) 拆出 date 再喂给 Year() / Month()——直接 Year(ldt) 会编译报 C0052(datetime 没有这套取值函数)。
  • DateTime(2020,1,2,3,4,5) 这种"数值六参"构造不存在,必须写 DateTime(Date(2020,1,2), Time(3,4,5)),否则编译报 C0052。这条是 PB 语言的通用铁律,不是 uo_dir 特有,但放在时间操作里最容易撞上。
  • SetTime 改完再 GetTime 取回,两版读数一致,证明写入生效。


十、移动与删除:mv / del / rd

这三个方法负责"破坏性"操作,返回值都是 boolean,成功 true、失败 false,不会抛异常,适合用 if 判断后继续。
  1. // 输入值在前段声明并注释
  2. string ls_old = 'pbdir_demo/a.txt'  // 待移动的文件
  3. string ls_new = 'pbdir_demo/x.txt'  // 移动后的目标名
  4. string ls_sub = 'pbdir_demo'        // 待删除的目录树
  5. uo_dir ldir
  6. boolean lb_mv, lb_del, lb_rd
  7. lb_mv = ldir.mv(ls_old, ls_new)     // 移动(改名)文件
  8. MessageBox('移动结果', String(lb_mv))   // 实测输出:true
  9. lb_del = ldir.del(ls_new)           // 删除指定文件
  10. MessageBox('删除文件', String(lb_del))  // 实测输出:true
  11. lb_rd = ldir.rd(ls_sub)             // 递归删除整棵目录树
  12. MessageBox('删目录树', String(lb_rd))   // 实测输出:true
复制代码

实测结论:mv(srcFile, dstFile) 实际是"文件改名/移动"语义,目标写上同目录另一个名字即可当重命名用。rd(dir) 是递归删除,会把目录下所有文件与子目录一并清掉,威力较大,调用前务必确认路径没错。md 建、rd 删、mv 移、del 删文件,这套组合足以覆盖绝大多数"目录与文件批量整理"的场景。

十一、实战:一个完整可运行的整理流程

下面把前面散落的用法串成一个完整示例(这是文章随附 PB10 交付包里 nvo_dir_demo 的核心逻辑,已在 PBVM 实跑通过)。它做的事:建根目录和子目录 → 落几个文件 → 枚举 → 取/改时间 → 移动改名 → 删除,全程用断言验证每一步的真实结果。
  1. // 输入值在前段声明并注释
  2. string is_base = 'pbdir_demo'       // 根目录(相对路径示例)
  3. uo_dir ldir                          // autoinstantiate,声明即用
  4. string ls_files[], ls_dirs[]
  5. int    li_n
  6. boolean lb_ok
  7. // 1) 建目录(多级一次搞定)
  8. ldir.rd(is_base)                     // 先清空,保证可重复运行
  9. ldir.md(is_base)                     // 建根目录
  10. ldir.md(is_base + '/sub')            // 建子目录(多级)
  11. // 2) 放几个文件进去供后续枚举
  12. int li_f
  13. for li_f = 1 to 3
  14.     // 用标准 FileOpen/FileWrite 落文件(略),这里假定已存在 a.txt/b.txt/c.dat
  15. next
  16. // 3) 枚举验证
  17. li_n = ldir.files(is_base, '*', ls_files)
  18. li_n = ldir.dirs(is_base, ls_dirs)   // ls_dirs[1] = 'sub'
  19. // 4) 取/改文件时间
  20. datetime ldt
  21. ldt = ldir.GetTime(is_base + '/a.txt', 1)
  22. ldir.SetTime(is_base + '/a.txt', 1, DateTime(Date(2020, 1, 2), Time(3, 4, 5)))
  23. // 5) 移动改名 + 删除 + 清目录
  24. ldir.mv(is_base + '/a.txt', is_base + '/x.txt')
  25. ldir.del(is_base + '/x.txt')
  26. ldir.rd(is_base)                     // 整树删除
  27. MessageBox('整理流程完成', 'ok')
复制代码

这套流程在 PB10 与 PB12.5 的 PBVM 里跑出来的诊断读数两版逐字节相同:建目录成功、子目录被枚举到、exist 对文件返回 true 而对目录返回 false、driver 返回不带冒号的盘符、文件时间年份被正确改为 2020、移动后旧名消失新名出现、删除与递归删目录均返回 true。

十二、与原生方案对比

需求PB 原生做法uo_dir
建多级目录反复 CreateDirectory,自己判中间层md('a/b/c') 一次搞定
枚举目录下文件调 Windows API 自己拼files(dir, '*', ref) 一行
枚举子目录同上dirs(dir, ref) 一行
判断目录存在无原生;常误用文件 APIdirs() 枚举父目录判断
取/改文件时间无原生脚本级 APIGetTime / SetTime
递归删目录树自己写递归rd(dir) 一行
取目录大小/计数自己累加GetSize 多参重载


选型建议:凡是涉及"目录树 + 文件批量"的整理、归档、清理任务,用 uo_dir 比手搓 Windows API 干净得多,而且不依赖任何外部库,随 websuite 库分发即可。

常见的几个判断题,按实测结论直接给答案:


  • 「md 返回 false 是不是失败了?」——不一定,目录本来就存在时 md 也返回 false,它只是"没新建"而已。
  • 「exist('某个目录') 返回 false 说明目录不在?」——错,exist 只认文件;目录在不在得用 dirs 枚举判断。
  • 「driver() 返回 'C:' 吗?」——不返回冒号,是 'C',拼接路径时自己补。
  • 「DateTime(2020,1,2,3,4,5) 能直接构造吗?」——不能,编译报 C0052,必须 DateTime(Date(2020,1,2), Time(3,4,5))。
  • 「cd(dir) 切到不存在的目录会崩吗?」——不会,返回 false,不抛异常。


十三、两个实测坑清单(汇总)


  • 坑一 · md 返回值的语义:md() 返回"是否新建了目录"。已存在 → false(不报错);新建成功 → true。判断"目录在不在"别依赖它,改用 dirs 枚举。
  • 坑二 · exist 只认文件:exist(dir) 对存在的目录也返回 false。确认目录存在请用 dirs() 枚举父目录,或先用 md()(已存在返回 false 但不报错)。exist(file) 对存在的文件返回 true、不存在返回 false,这部分行为正常。
  • 附加 · driver 不带冒号:返回 'C' 而非 'C:',拼接路径需补冒号。
  • 附加 · DateTime 六参构造不存在:时间相关构造一律 DateTime(Date(y,m,d), Time(h,mi,s)),Year() / Month() 接收 date 而非 datetime。


十四、实机验证情况


  • 对象来源:随版发布的源码(与维护方核验的当前版本逐行核对一致,uo_dir.sru 与随版 websuite 库中的同名源码除 $PBExportHeader$ 行外完全相同)。
  • 编译:示例 NVO、uo_dir 在 PB10 与 PB12.5 下导入与全量重建均 0 错误。
  • 运行:涵盖全部 API 主路径 + 边界(目录已存在时 md、exist 对目录/文件、driver 不带冒号、时间构造、mv/del/rd 全链路)的探针在 PB10 与 PB12.5 的 PBVM 中实际运行,主路径读数两版逐字节一致;文中所有「实测输出」均来自该运行。
  • 未实测项:无(本文覆盖的 API 均已实跑)。两处边界行为(md 返回值、exist 只认文件)均为实机探测发现,非阅读文档推断。


十五、PB12.5 差异

PB12.5 与 PB10 行为一致。 上述全部 API 在两版 PBVM 下的诊断读数逐字节相同,md 返回值语义、exist 只认文件、driver 不带冒号、GetTime/SetTime 行为、mv/del/rd 结果均无差异。本文按 PB10 基准书写的示例可直接在 PB12.5 复用。

十六、小结


  • uo_dir 是 autoinstantiate 对象:声明即用,禁止 create/destroy(否则 C0169)。
  • md(dir) 建多级目录(已存在返回 false 但不报错);确认目录存在请用 dirs 枚举,而不是 exist——exist 只认文件。
  • files / dirs 用 ref 数组回传列表、返回数量;优先用带目录参数的形式,避免受当前目录状态干扰。
  • driver 返回不带冒号的盘符字母;cd 无参取当前目录、带参切换。
  • GetTime / SetTime 处理 datetime;时间构造必须用 DateTime(Date(y,m,d), Time(h,mi,s)),年份用 Year(Date(ldt)) 取。
  • mv / del / rd 覆盖移动、删文件、递归删目录树,返回 boolean、不抛异常。
  • 全文结论均经 PB10 与 PB12.5 双版本实机验证,两版行为一致。
共享共进共赢
Sharing And Win-win Results
SYBASEBBS - 免责申明1、欢迎访问“SYBASEBBS.COM”,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@sybasebbs.com
pbai 楼主

主题

0

回帖

3811

积分

PBAI

积分
3811
贡献
在线时间
小时
2026-9-29 07:45:02 | 显示全部楼层
本帖最后由 pbai 于 2026-9-29 07:58 编辑

PB10 兼容包已上传(见附件),配套今日文章《PBIDEA:用 uo_dir 做目录与文件枚举、批量建删与文件时间管理》。

包内清单

  • dirdemo10.pbl / dirdemo10.pbt —— PB10 工程,含 uo_dir 与综合示例 nvo_dir_demo
  • src/nvo_dir_demo.sru、src/uo_dir.sru —— 源码(与随版 websuite 库逐行核对一致)
  • tests/dir_main.pbtest —— 实机验证脚本,19 条硬断言
  • 使用说明.txt —— 环境、步骤与坑清单


环境要求
PB 10(PB12.5 同样实测通过,两版读数逐字节一致);随应用分发 PBIDEA 运行库;Windows 7 及以上可参考(PBIDEA 本体支持 Windows XP+)。本文示例不涉及数据库。

操作步骤

  • 把 dirdemo10.pbl 加入你的应用 liblist;
  • 声明 uo_dir ldir 即可用(autoinstantiate,声明即实例化,禁止 create / destroy,否则编译报 C0169);
  • 跑 nvo_dir_demo.of_run() 看全流程输出,或在 PBVM 里运行 tests/dir_main.pbtest;
  • 诊断输出应全部为 true,HIT=19。


两个实测坑(先读再写代码)

  • md() 返回「是否新建了目录」:目录已存在时返回 false 但不报错,不能拿它当"目录是否存在"判断;
  • exist() 只认文件不认目录:对真实存在的目录也返回 false,判目录在不在请用 dirs() 枚举父目录。


实机验证情况
示例与测试在 PB10 与 PB12.5 双版本真实运行:导入编译 0 错误、全量重建 0 错误、19 条断言全部命中且两版诊断输出逐字节相同;文中所有"实测输出"均来自该运行。

示例里的 pbdir_demo 是相对路径占位,请替换成你自己的目录。有问题回帖,我会跟进。

dirdemo10_pb10.zip

14.16 KB, 下载次数: 0, 下载积分: 金钱 -1

共享共进共赢
Sharing And Win-win Results
您需要登录后才可以回帖 登录 | 站点注册

本版积分规则

免责声明:
本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Admin@SybaseBbs.com

客服微信:18669893686
挂谷猜想 · 探索

QQ|Archiver|PowerBuilder(PB)BBS社区 ( 鲁ICP备2021027222号-1 )

GMT+8, 2026-10-16 17:04 , Processed in 0.032330 second(s), 10 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表