明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 418|回复: 2

[源码] 导出变量设置到文件

[复制链接]
发表于 2020-10-2 00:45 | 显示全部楼层 |阅读模式
本帖最后由 wyl219 于 2020-10-2 00:49 编辑

实际是看到http://bbs.mjtd.com/thread-182383-1-1.html里的一个想法,把变量的内容保存到文件内,方便将来读取.

其实网上已经有现成的方法了,即保存到ini文件里,参见:https://blog.csdn.net/yxp_xa/article/details/72539877

vectra大佬提出了一个想法,直接保存为lsp文件,用的时候直接read一下,之前没考虑过这方面的内容,确实是个不错的选择.

不过这个办法有个缺点,就是不能选择性的加载内容,因此花了点时间写了两个小函数,没经过很详细的测试,只知道不能用于保存匿名函数.带了两个示例程序.比较特别的是,函数运行后,会直接把变量的值赋给保存的变量名,而不需要像ini文件那样,需要外嵌一个setq函数,确定就是不能随时修改变量名.

希望能让更多人看到讨论,单独发了个帖子.



;|
说明:
示例程序:导出变量
|;

(defun c:tt1 ( / file_name a b c d e )
        (setq file_name "d:\\test.setting");可以设定为全局变量或局部变量,当设定为局部变量时,可用于每个程序保存为独立的文件.
        (setq a 1 ;数字变量
                b "2" ;字符串变量
                c (list 1 2 "a") ;列表变量
                d 'list ;函数变量,可能只能用于系统自带函数
                e '(lambda nil 1) ;用户函数变量,实际上是个列表
                ; 如果不加前面的',作为匿名函数,保存的是函数的id,实际上是不能读取的
        );初始化变量
        (wyl:save_var "d:\\test.setting" (list "a" "b" "c" "d" "e") "" )
        (getstring "已保存变量a至e,按空格键继续")
        (setq a 3
                b "1"
        );修改变量
        (wyl:save_var "d:\\test.setting" "a" "up" )
        (getstring "已更新变量a的值,按空格键继续")
        (wyl:save_var "d:\\test.setting" "c" "" )
        (princ "已保存变量b,并删除其他内容")
                (wyl:save_var "d:\\test.setting" (list "a" "b" "c" "d" "e") "" )
        (princ "示例程序结束,并重新保存所有变量,用于示例2")
)

;|
说明:
示例程序:导入变量
|;

(defun c:tt2 ( / file_name a b c d e f g )
        (setq file_name "d:\\test.setting");可以设定为全局变量或局部变量,当设定为局部变量时,可用于每个程序保存为独立的文件.
        (print "之前各项的值(应该均为nil):")
                (print (strcat "a:" (vl-princ-to-string a) "type:"  (vl-princ-to-string (type a))))
                (print (strcat "b:" (vl-princ-to-string b) "type:"  (vl-princ-to-string (type b))))
                (print (strcat "c:" (vl-princ-to-string c) "type:"  (vl-princ-to-string (type c))))
                (print (strcat "d:" (vl-princ-to-string d) "type:"  (vl-princ-to-string (type d))))
                (print (strcat "e:" (vl-princ-to-string e) "type:"  (vl-princ-to-string (type e))))
                (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        
        (getstring "导入各项变量,并且不获取未找到的变量\n")
        (wyl:load_var "d:\\test.setting" (list "a" "b" "c" "d" "e" "f") nil )
                (print (strcat "a:" (vl-princ-to-string a) "type:"  (vl-princ-to-string (type a))))
                (print (strcat "b:" (vl-princ-to-string b) "type:"  (vl-princ-to-string (type b))))
                (print (strcat "c:" (vl-princ-to-string c) "type:"  (vl-princ-to-string (type c))))
                (print (strcat "d:" (vl-princ-to-string d) "type:"  (vl-princ-to-string (type d))))
                (print (strcat "e:" (vl-princ-to-string e) "type:"  (vl-princ-to-string (type e))))
                (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        (print "b应该是str,c、e是list,d是SYM,f应该是nil")
        
        (getstring "导入未找到的变量f,并用默认获取方式(即getstring)\n")
        (wyl:load_var "d:\\test.setting" "f" "" )
        (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        
                (getstring "导入未找到的变量f,并用getint获取方式(获取到的数据类型是int)\n")
        (wyl:load_var "d:\\test.setting" "f" '(getint "f的数值") )
        (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        
                        (getstring "导入未找到的变量f,并用字符串函数获取\n")
        (wyl:load_var "d:\\test.setting" "f" "(getint \"f的大小\")" )
        (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        
                                (getstring "导入未找到的变量f、g,并用字符串函数获取,例如需要获取为int并且想使用默认的提示语\n")
        (wyl:load_var "d:\\test.setting" '("f" "g") "(getint msg)" )
        (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        (print (strcat "g:" (vl-princ-to-string g) "type:"  (vl-princ-to-string (type g))))
        
                                        (getstring "导入未找到的变量f、g,并用自定函数获取,例如需要将输入的数值乘以1000\n")
        (wyl:load_var "d:\\test.setting" '("f" "g") '(lambda nil (* 1000 (getreal "输入米数"))) )
        (print (strcat "f:" (vl-princ-to-string f) "type:"  (vl-princ-to-string (type f))))
        (print (strcat "g:" (vl-princ-to-string g) "type:"  (vl-princ-to-string (type g))))
        
)


;|
说明:
参数:file_path:文件的绝对路径,或当文件在支持文件中时可以是文件名,路径中的\用\\代替
var_list:需要导出的变量名列表,注意,是变量名,而不是变量,即"a"这样的字符串形式.当只有一个变量的时候可以用字符串而不是列表
mode:保存模式.当mode为"up"时,会保留除此次保存的变量之外的其他变量,否则将只保留本次保存的变量.
返回值:t
示例:
保存a b c 三个变量到文件
(wyl:save_var "d:\\test.setting" (list "a" "b" "c") )
更新a b 变量到文件
(wyl:save_var "d:\\test.setting" (list "a" "b") "up")
保存 a 变量到文件,并不保留其他内容
(wyl:save_var "d:\\test.setting"  "a" "" )
|;
(defun wyl:save_var( file_path var_list mode / fn bo new_var_list this )
        (if (eq 'str (type var_list))
                (setq var_list (list var_list))
        ); var_list如果是字符串,则转换成列表
        
        (if (eq mode "up")
                (progn
                        ; 开始读取原有配置
                        (setq fn (open file_path "r"))
                        (setq new_var_list '())
                        (while (setq this (read-line fn));当文件读完以后 read-line返回nil
                                (setq new_var_list (cons this new_var_list))
                        )
                        (close fn) ; 关闭文件
                        
                        (foreach x var_list ;循环x=需要保存的变量
                                (setq bo t) ; 临时变量,当bo=t表示未在原有记录中找到x变量
                                (foreach y new_var_list; 循环 y=原有变量中的每一个条目
                                        (if (wcmatch y (strcat "(setq " x " *"))
                                                (progn
                                                        (setq new_var_list (cons
                                                                                                                                         (strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
                                                                                                                                         ;拼成(setq a 1)的形式,read和eval均不能少
                                                                                                                                         ;当变量为字符串类型时,prin1的形式是"1",princ的形式是1,即princ导出的字符串是错误的
                                                                                                                                         ;变量内容前会加一个',否则当变量内容是表时,read-eval后,会把这部分当成一个函数处理
                                                                                                                                         (vl-remove y new_var_list); 从列表中删除原有条目
                                                                                                                                 )
                                                               
                                                        )
                                                        (setq bo nil) ;找到变量后跳过下一步
                                                )
                                        )
                                ) ; end foreach y
                                (if bo (setq new_var_list (cons
                                                                                                                                                (strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
                                                                                                                                                new_var_list
                                                                                                                                        ))
                                       
                                );如果没在原记录中找到对应项,则单独加入
                        ); end foreach x
                ) ;end progn
                (progn ;当mode不等于up时
                        (setq new_var_list '())
                        (foreach x var_list
                                (setq new_var_list (cons
                                                                                                                 (strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
                                                                                                                 new_var_list
                                                                                                         )
                                       
                                )
                        )
                );end progn
        );end if
        ; 开始写入配置文件
        (setq fn (open file_path "w"))
        (foreach x new_var_list
                (write-line x fn)
        )
        (close fn)
        t ;返回t
)



;|
说明:
参数:file_path:文件的绝对路径,或当文件在支持文件中时可以是文件名,路径中的\用\\代替
var_list:需要导入的变量名列表,注意,是变量名,而不是变量,即"a"这样的字符串形式.当只有一个变量的时候可以用字符串而不是列表,当需要导入所有变量时,var_list可以是空字符串、"*"或nil.
fun:当未找到变量时,如何处理,当fun=nil时,不处理,当fun为字符串或函数时按照内容处理,当fun为空字符串时,采用默认处理方式,当字符串形式的代码时,如果代码中有引号,需要用\"代替
返回值:t
示例:
从文件中读取变量a,当文件中无a的记录时,不获取值
(wyl:load_var "d:\\test.setting" "a" nil )
从文件中读取变量a 和b ,当文件每无相应的记录时,通过默认方式获取值
(wyl:load_var "d:\\test.setting" (list "a" "b") "" )
从文件中读取变量a,当文件中无a的记录时,通过给定的函数处理
(wyl:load_var "d:\\test.setting" "a" '(getint "输入高度") )
从文件中读取变量a 和b ,当文件每无相应的记录时,通过字符串函数获取值
(wyl:load_var "d:\\test.setting" (list "a" "b") "(getint \"输入高度\")" )
|;
(defun wyl:load_var(file_path var_list fun / fn new_var_list bo msg)
        ; 格式化参数
        (cond
                ((or (eq "" var_list) (not var_list))
                        (setq var_list '("*"))
                )
                ((eq 'str (type var_list))
                        (setq var_list (list var_list))
                )
                (t)
        );end cond
        (if (eq fun "")
                (setq fun "(getstring msg)")
        )
        ; 开始原有配置
        (setq fn (open file_path "r"))
        (setq new_var_list '())
        (while (setq this (read-line fn));当文件读完以后 read-line返回nil
                (setq new_var_list (cons this new_var_list))
        )
        (close fn) ; 关闭文件
        
        ;开始应用配置
        (foreach x var_list
                (foreach y new_var_list
                        (setq bo t)
                        (if (wcmatch y  (strcat "(setq " x " *"));如果是要恢复的条目,注意这里的判断和save里的判断和保存的形式需要相同
                                (progn
                                        (eval (read y))
                                        (setq bo nil)
                                )
                        );end if
                ); end foreach y
                (if (and bo fun (not (eq "*" x))) ;当没有找到变量,并且变量不为*时,由用户输入变量
                        (if (or (eq 'list (type fun)) (eq 'SUBR (type fun)))
                                (set (read x) (eval fun)); 如果fun是个函数
                                (progn ; 如果fun是个字符串
                                        (setq msg (strcat"请输入变量" x "的值:"))
                                        (set (read x) (eval (read fun)));这里是set而不是setq
                                );end progn
                        ) ;end if
                );end if
        ); end foreach x
        t ;返回t
)




本帖子中包含更多资源

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

x

评分

参与人数 1明经币 +1 收起 理由
vectra + 1 淡定

查看全部评分

发表于 2020-10-2 20:32 | 显示全部楼层
本帖最后由 wzg356 于 2020-10-2 20:37 编辑

不用那么复杂,假定你要保存的是'a 'b 'c 'd 'e 5个变量
把它列成表
(list a b c d e)====>(1 2 ("a" 3) nil "5")

变量结果写入文件file三行码
只保存结果就行,因为这是专用数据
(setq f(open file "w"))
(write-line(vl-prin1-to-string (list a b c d e)) f)
(close f)

从文件读出保存的变量三行码
(setq f (open file "R"))
(setq STR (read-line F))
(close F)


把读出的结果赋值给'a 'b 'c 'd 'e 5个变量
(mapcar 'set (list 'a 'b 'c 'd 'e)(eval(read STR)))

评分

参与人数 1明经币 +1 收起 理由
vectra + 1 赞一个!

查看全部评分

发表于 2020-10-2 20:44 | 显示全部楼层
如果变量结果只是加载lsp的时候使用,可把结果写在lsp文件末尾或开头(读取后添加)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-18 18:05 , Processed in 0.214372 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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