2.1 批量输入/输出: "batch-io.rkt"
(require 2htdp/batch-io) | package: htdp-lib |
batch-io教学包引入了用于从文件中读取内容的几个函数和一个语法形式,以及一个用于写文件的函数。
2.1.1 IO函数
- 读取标准输入设备(直到其被关闭)或文件f的内容,返回包含换行符的字符串。例如:
> (read-file "data.txt") "hello world \n good bye \n\ni, for 1, am done "
其中文件"data.txt"的内容是:hello world
good bye
i, for 1, am done
注意第二行中的前导空格转换为结果中换行符和"good"之间的空格。 函数
(read-1strings f) → (listof 1string?)
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回单字符字符串的表,每个字符一个字符串。例如:> (read-1strings "data.txt") '("h"
"e"
"l"
"l"
"o"
" "
"w"
"o"
"r"
"l"
"d"
" "
"\n"
" "
"g"
"o"
"o"
"d"
" "
"b"
"y"
"e"
" "
"\n"
"\n"
"i"
","
" "
"f"
"o"
"r"
" "
"1"
","
" "
"a"
"m"
" "
"d"
"o"
"n"
"e"
" ")
注意此函数忠实地再现文件的所有部分,包括空格和换行符。函数
(read-lines f) → (listof string?)
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回字符串的表,每行一个字符串。例如:> (read-lines "data.txt") '("hello world " " good bye " "" "i, for 1, am done ")
其中"data.txt"是和前一个例子相同的文件。同样,第二行中的前导空格出现在表中第二个字符串中。即使最后一行不以换行结束,函数也假设如此。
函数
(read-words f) → (listof string?)
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回字符串的表,文件中空格每个空格区分的词一个字符串。。例如:> (read-words "data.txt") '("hello" "world" "good" "bye" "i," "for" "1," "am" "done")
然而,这一次"data.txt"第二行的额外前导空格不在结果中。 此空格被认为是围绕"good"一词的分隔符的一部分。函数
(read-words/line f) → (listof (listof string?))
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回表的表,每行一个表;行表示为字符串的表。例如:> (read-words/line "data.txt") '(("hello" "world") ("good" "bye") () ("i," "for" "1," "am" "done"))
结果和read-words返回的类似,区别是文件中的分行信息得以保留。特别地,空白行由空表表示。即使最后一行不以换行结束,函数也假设如此。
函数
(read-words-and-numbers/line f) → (listof (or number? string?))
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回表的表,每行一个表;行表示为字符串或数值的表。例如:> (read-words-and-numbers/line "data.txt") '(("hello" "world") ("good" "bye") () ("i," "for" "1," "am" "done"))
结果和read-words/line返回的类似,区别是可以的话将字符串解析为数值表示。即使最后一行不以换行结束,函数也假设如此。
函数
(read-csv-file f) → (listof (listof any/c))
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回逗号分隔值表的表。例如:> (read-csv-file "data.csv") '(("hello" "world") ("good" "bye") ("i" "am" "done"))
其中文件"data.csv"的内容是:hello, world
good, bye
i, am, done
需要理解的是,行不必具有相同的长度。这个例子中,第三行包含三个元素。函数
(read-csv-file/rows f s) → (listof X?)
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) s : (-> (listof any/c) X?) 读取标准输入设备(直到其被关闭)或文件f的内容,返回行的表;读取文件f的内容,将每行通过s构造为数据。例如:> (read-csv-file/rows "data.csv" (lambda (x) x)) '(("hello" "world") ("good" "bye") ("i" "am" "done"))
> (read-csv-file/rows "data.csv" length) '(2 2 3)
第一个例子显示read-csv-file就是read-csv-file/rows的缩写形式; 第二个例子计算每一行词的数量,结果就是数值的表。在许多场景下,函数参数可以从行中构造结构体。函数
(read-xexpr f) → xexpr?
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回包含诸如制表符、换行符等空格的X表达式。假设:文件f或者所选的输入设备包含XML元素。假定文件包含类似HTML的文本并将其读入为XML。
例如:> (read-xexpr "data.xml") '(pre () "\nhello world\ngood bye\n\ni, for 1, am done\n")
其中文件"data.xml"的内容是:<pre>
hello world
good bye
i, for 1, am done
</pre>
注意结果包含换行符"\\n"。函数
(read-plain-xexpr f) → xexpr?
f : (or/c 'standard-in 'stdin (and/c string? file-exists?)) 读取标准输入设备(直到其被关闭)或文件f的内容,返回不包含空格的X表达式。假设:文件f或者所选的输入设备包含XML元素,该元素的内容是其他XML元素和空格。 特别地,XML元素不包含任何除空格之外的字符串元素。
例如:> (read-plain-xexpr "data-plain.xml") '(pre
()
(line ((text "hello world")))
(line ((text "good bye")))
(line ())
(line ((text "i, for 1, am done"))))
其中文件"data-plain.xml"的内容是:<pre>
<line text="hello world" />
<line text="good bye" />
<line />
<line text="i, for 1, am done" />
</pre>
将此与read-xexpr的结果比较。
函数
(write-file f cntnt) → string?
f : (or/c 'standard-out 'stdout string?) cntnt : string? 将cntnt送往标准输出设备,或将cntnt转化为文件f的内容,该文件与程序位于同一文件夹(目录)中。 如果写入成功,函数返回文件名(f);否则它会抛出错误。例如:> (if (string=? (write-file "output.txt" "good bye") "output.txt") (write-file "output.txt" "cruel world") (write-file "output.txt" "cruel world")) "output.txt"
对这个例子求值后,文件"output.txt"的内容就是:cruel world
解释为什么。
函数
(file-exists? f) → boolean?
f : string?
警告:此教学包中的文件IO函数和操作系统相关。这就是说,只要程序和文件位于同一平台上, 读取程序写入的文件就不会有任何问题,反之亦然。但是,如果某个程序在Windows操作系统上写入文件, 然后将此输出文件复制到Mac,那么读取复制后的文本文件可能会产生多余的“return”字符。请注意, 这仅描述了一种可能出现的故障;很多在其他情况下,跨平台操作都可能会导致本教学包失效。
2.1.2 网页函数
所有读取基于网页的XML的函数都读入URL以及其他可选参数。 它们假设计算机可以接到指定的网页,但也容忍网页不存在(404错误)。
函数
(read-xexpr/web u) → xexpr?
u : string? 函数
(read-plain-xexpr/web u) → xexpr?
u : string? 函数
(url-exists? u) → boolean?
u : string? 确保指定的URL u不会给出404错误。- 判读输入值在以下意义上是否是X表达式:
; Xexpr是以下之一: ; – symbol? ; – string? ; – number? ; – (cons symbol? (cons [List-of Attribute] [List-of Xexpr])) ; – (cons symbol? [List-of Xexpr]) ; ; Attribute是: ; (list symbol? string?) ; (list 'a "some text")被称为a-Attribute, ; 其中"some text"是a的值。 请注意,完整的Racket使用更广泛的X表达式概念。 函数
(xexpr-as-string x) → string?
x : xexpr? 将输入的X表达式呈现为字符串。函数
(url-html-neighbors u) → (listof string?)
u : string? 检索URL u的内容,生成其中所有通过<a>标签引用的.html页面的表。
2.1.3 测试
语法
(simulate-file process str ...)