【风格】文件处理之传统与对象

作者:amnesiac 首发:官方论坛中文版

注:对于 AutoHotkey,初学者几乎都会困惑的一点是可选的风格很多,初学者多感觉语法凌乱,而熟悉的人则认为灵活多样,这点是好是坏见仁见智了。不过这种现象的产生有一定的历史原因,以后可能会做更详细的说明。

与文件系统交互是脚本中最常见的操作之一。本文从文件处理的角度比较传统方式和对象方式的一些差异,以便整体上对它们有一定的理解,避免混乱。比较而言,两种方式的差异:

  • 命令较简单(有批处理的感觉),能满足大部分需求 ;
  • 对象则更灵活,可进行更精细的控制,用的好也更高效;

文件处理的传统命令

AutoHotkey 中主要为操作文件提供了下列命令(和函数):

FileAppend:附加内容到文件末尾,若文件不存在则首先创建文件。
FileDelete:删除文件。
FileRead/FileReadLine/文件读取循环:读取整个文件或某行文件的内容,或者从文件头部开始逐行获取文件的内容。
FileExist():判断文件、文件夹是否存在。
文件和文件夹循环:遍历文件系统中指定位置的文件和文件夹。
其他命令:与文件相关的其他命令。

首先设置需要操作的目标文件:

strFileName := "C:\Test.txt"

FileAppend

附加一些内容到文件末尾,当目标文件不存在时会首先创建文件:

FileAppend, 需要追加的文本。`n, %strFileName%

FileDelete

删除文件。例如:

FileDelete, %strFileName%

如果需要覆盖文件,则需要首先使用 FileDelete 删除文件(传统方式中没有直接覆盖的命令)。

FileRead/FileReadLine/文件读取循环

使用 FileRead 可以一次性读取整个文件的内容:

FileRead, strFile, %strFileName%

如果只需要读取文件的少数几行,请使用 FileReadLine:

intLineNum := 1 ; 设置需要读取的行号。
FileReadLine, strRow, %strFileName%, %intLineNum%

如果需要逐行处理文件内容,则使用循环比较方便(比 FileReadLine 效果更好):

strObjectFileName := "C:\Object.txt" ; 设置用来存放处理后的数据的目标文件。
Loop, Read, %strFileName%, %strObjectFileName%
{
  MsgBox, 第 %A_Index% 行的内容为 %A_LoopReadLine%。
}

注意:只有在文件读取循环中才存在 A_LoopReadLine 变量。此外,在这种循环中需要写入文本时建议使用仅带一个参数(写入的文本)的 FileAppend 命令,这样执行地更高效。

FileExist()

判断文件、文件夹是否存在。例如:

if FileExist(strFileName)
  MsgBox, 目标存在。

文件和文件夹循环

使用 Loop 循环遍历文件系统中指定位置的文件和文件夹(与上面读取文件内容不同):

strObjectDir := "C:\*"
Loop, %strObjectDir% ; 仅获取文件。
{
  MsgBox, 在 %strObjectDir% 中第 %A_Index% 个文件的名称为 %A_LoopFileName%。
}

注意:这个 Loop 循环中存在许多自己特有的变量,许多时候很有用。

其他命令

上面介绍了操作文件、文件夹时的主要命令,还有一些较不常用的,这里提一下:

FileCopy:复制文件。
FileCopyDir:复制目录(类似批处理中的 xcopy)。
FileCreateDir:创建目录。
FileMove:移动或重命名文件。
FileMoveDir:移动或重命名目录。
FileRemoveDir:删除目录。

小结

上面介绍了文件、文件夹操作的主要命令,其中的读取、写入命令大多数情况下都是操作文本文件,不过一些也能操作二进制文件。另外,对于与文件编码、大小、属性等方面相关的命令,这里没有进行说明,请参阅帮助。

文件对象

创建文件对象

使用 FileOpen() 函数:

strFileName := "C:\Test.txt"
objFile := FileOpen(strFileName, "r", "UTF-8")
if ObjFile
  MsgBox, 文件 %strFileName% 打开成功。

在创建对象后,必须立即判断是否创建成功,初学者容易忽略这点。

操作文件

这些操作是文件句柄的方法,所以必须首先通过 FileOpen() 获取文件句柄才能调用这些方法:

Read:从文件当前指针位置读取字符串并使文件指针向前移动。
Write:写入字符串到文件的当前指针位置并使文件指针向前移动。
ReadLine:从文件中读取一行文本并使文件指针向前移动。
WriteLine:写入字符串后面跟着 `n 或 `r`n,取决于打开文件时使用的标志。使文件指针向前移动。
RawRead:从文件读取原始的二进制数据到内存。
RawWrite:写入原始的二进制数据到文件。
AtEOF:判断文件指针是否到达文件末尾。
Close:关闭文件,把缓冲区的数据写入磁盘并释放共享锁定。

上面是文件对象常用的方法和属性(其中只有 AtEOF 是属性),其他方法和属性请参阅帮助。

文件对象用法模板

FileName := "d:\test.txt"
ObjFile := FileOpen(FileName, "r")
if !IsObject(ObjFile) ; 另一种判断文件对象是否创建成功的方法。
{
  MsgBox, 文件 %FileName% 打开失败。
  return
}

Loop ; 此处可能 While 循环较好,后续文章中我会比较几种循环的差异。
{
  If ObjFile.AtEOF ; 判断是否到了文件末尾
    break
  Text := ObjFile.ReadLine()
  MsgBox, 第 %A_Index% 行文本为: %Text%
}
ObjFile.Close() ; 结束操作后必须关闭对象,以释放资源。

这个文件对象的使用模板,就像武术中的套路,在需要时适当调整一下很方便用到自己的脚本中。

文件命令与对象的比较

命令简单就不解释了,不过上面的内容也许还不容易看出文件对象的强大,所以这里做个小结:文件对象的强大在于它的灵活,尝试使用它的几个方法会对此有所理解,尤其在处理二进制内容的情况时(这方面命令的功能极其有限);文件对象的高效则在于对同一文件进行大量的读取、写入操作时,我们都知道 I/O 操作是比较耗时的,在大批量文件处理时十分明显。

对于初学者,从命令开始吧,基本都能满足需求(需要文件对象的强大之处实际使用相对较少),熟悉后可以适当了解文件对象。到最后,会选择使用哪种风格往往成了个人习惯,而与其他关系不大。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,204评论 9 467
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,930评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • ❀很多时候 ❀背着书包去遥远的地方 ❀是一种享受
    绫人lL阅读 209评论 2 3
  • 原创2016-08-29喝豆浆的猫文字原作 文/喝豆浆的猫 配图·喝豆浆的猫 2016年8月25日,下午五点,我坐...
    陈霓裳阅读 450评论 0 25