Engee 文档

输入/输出功能

Julia 中的输入/输出功能提供了处理文件、数据流和其他数据源/接收器的能力(见I/O和网络 )。对于导入文件浏览器的文件,可以应用函数:

发现

open - 打开文件或数据流。

Details

open "函数可以方便安全地处理文件,因为在 "open "调用的上下文中使用文件后,文件会自动关闭,这有助于避免资源泄漏或其他与隐式保留打开文件相关的问题。

该函数将 f 函数应用于结果 open(args...; kwargs...) 并在完成后关闭结果文件描述符。

open(f::Function, args...; kwargs...)

文件描述符是一个抽象概念,用于在程序中表示打开的文件。它是一种数据结构,包含文件的相关信息,如文件路径、访问模式(读、写等)、当前在文件中的位置以及其他属性。例如

write("my_file.txt", "Hello world!"); # 正在创建一个文件my_file。txt包含文本Hello world!

open(io->read(io, String), "my_file.txt")
"Hello world!" # 打开my_file。txt进行读取,并立即将其内容读取成字符串

rm("my_file.txt") # 删除my_file。txt后其内容已被读取并输出

io->read(io, String) 函数接收 I/O 对象 (io),并将其内容读入字符串。然后将文件 "my_file.txt "的内容作为结果输出,最终结果是字符串 "Hello world!"。


以五个逻辑参数指定的模式打开文件:

open(filename::AbstractString; lock = true, keywords...) -> IOStream

关键字

描述

默认。

读取

创建
截断
添加

打开阅读
写入
如果不存在,则创建
修剪为零
搜索到底


Truncate`| append
读写`| 截断| `append
读写

默认情况下,如果没有传递关键字,文件将以只读方式打开。会返回一个线程来访问打开的文件。名为 lock 的参数指定是否锁定操作,以确保多线程访问的安全性。

另一种打开语法使用基于字符串操作的模式描述符,而不是五个逻辑参数。模式值与 fopen(3)Perl open 中的模式值相对应,并且 相当于设置以下逻辑组:

模式

描述

关键字

r
w
r+
w+
a+

阅读
读取、创建、修剪
读取、创建、连接
阅读、书写
读、写、创建、修剪
读、写、创建、连接

不 写入 = true
添加 = true
读取 = true,写入 = true
截断 = true, 读 = true
append = true, read = tru

*示例:

io = open("my_file.txt", "w"); # 打开my_file。txt写入(写入)

write(io, "Hello world!"); # 写字符串Hello world! 到上一行打开写入的文件

close(io); # 关闭my_file。txt,释放资源,完成写操作

io = open("my_file.txt", "r"); # 打开my_file。txt用于读取(read),返回一个输入/输出对象(io)

read(io, String) # 读取my_file文件的内容。txt作为字符串
"Hello world!" # 操作的结果

write(io, "This file is read only") # 由于文件是只读打开的(在上一行),因此不允许此写入操作,并且会生成ArgumentError错误。
ERROR: ArgumentError: write failed, IOStream is not writeable
[...]

close(io) # 关闭文件my_file。txt后写尝试释放资源

io = open("myfile.txt", "a"); # 打开my_file。txt添加(追加),这将允许写入数据到文件的末尾,而不删除或复盖其内容

write(io, "This stream is not read only") # 将行"This stream is not read only"写入文件my_file的末尾。txt,因为文件是在追加模式("a")下打开的。 Write函数返回写入的字节数(28)
28 # 操作的结果

close(io)# 关闭my_file。txt执行完所有写操作后释放资源

rm("my_file.txt") # 删除文件my_file。txt脧脗脭脴

阅读更多有关I/O和网络open 函数所有功能的信息。

isopen - 判断对象(线程或计时器)是否已经关闭。

Details

对象一旦关闭,就不能再创建新事件。不过,鉴于已关闭的线程可能仍有数据要在缓冲区中读取,因此应使用 eof 来检查数据是否可以读取。使用 FileWatching 软件包可在支持向流写入或从流读取数据时收到通知。如果对象处于打开状态,函数将输出 true;如果对象处于关闭状态,函数将输出 false

io = open("my_file.txt", "w+"); # 打开文件my_file。"w+"模式下的txt(写入和读取)

isopen(io) # 检查与io i/O对象关联的文件是否打开(my_file.txt)
true # 操作的结果

close(io) # 关闭与io i/O对象关联的文件。 关闭后,文件不再可用于写入或读取。

isopen(io) # 关闭文件后(之前的操作),该命令返回false,因为该文件不再打开。
false # 操作的结果

对于函数 io = open("my_file.txt", "w+")

  • 如果文件不存在,将创建该文件。

  • 如果文件已经存在,将删除其内容。

函数 open 还会返回一个与打开的文件相关联的 I/O 对象 (io)

关闭

close - 关闭 I/O 流。

Details

首先执行`flush`(强制重置 I/O)。

close(io)

closeall - 关闭图形用户界面上所有打开的窗口。

Details

如果你想在终止程序前确保所有文件都已关闭,那么它将非常有用。

closeall()

closeread - 仅关闭与 I/O 对象关联的文件读取线程。

Details

如果文件已打开供读写,则写入流仍保持打开。仅用于关闭读取流,但可以选择继续向文件写入。

closeread(io)

closewrite - 停止写入全双工 I/O 流的一半。

Details

首先执行`flush`操作。通知对方数据不再写入基础文件。某些 I/O 类型可能不支持此操作。

*示例

io = Base.BufferStream(); # 将创建一个新的缓冲输入/输出流。 在这种情况下,锁永远不会执行,因此读取和写入操作可用于相同的作业。

write(io, "request"); # 请求字符串写入缓冲的io流

# 在这里调用`read(io)`时,应用永久锁。

closewrite(io); # Io写流被关闭,不会接受任何写操作,而读流保持打开状态。

read(io, String) # 正在从io执行读取操作

录音

write - 将数值的规范二进制文件表示写入指定的 I/O 流或文件。

Details

返回写入数据流的字节数。写入值的字节顺序取决于主机系统中的字节顺序。

一次写入调用可以写入多个值,即以下值是等价的:

write(io, x, y...)
write(io, x) + write(io, y...)

例如

# 一致的序列化

fname = tempname(); # 任意临时文件名

open(fname,"w") do f
             # 确保以直接字节顺序格式写入64位整数值。
             write(f,htol(Int64(42)))
         end
8

julia> open(fname,"r") do f
             # 执行到基本字节顺序和基本整数类型的反向转换
             Int(ltoh(read(f,Int64)))
         end
42

# 组合写操作的调用:

io = IOBuffer();

write(io, "JuliaLang is a GitHub organization.", " It has many members.")
56

String(take!(io))
"JuliaLang is a GitHub organization. It has many members."

write(io, "Sometimes those members") + write(io, " write documentation.")
44

String(take!(io))
"Sometimes those members write documentation."

# 没有write方法的用户定义的核心数据类型可以被写入,并且,注意,封装在Ref中

struct MyStruct; x::Float64; end

io = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

write(io, Ref(MyStruct(42.0)))
8

seekstart(io); read!(io, Ref(MyStruct(NaN)))
Base.RefValue{MyStruct}(MyStruct(42.0))

iswritable - 检查是否支持写入指定对象。

Details

如果不支持写入指定的 I/O 对象,则返回 false

*`示例

open("my_file.txt", "w") do io
    print(io, "Hello world!");
    iswritable(io)
end
true

open("my_file.txt", "r") do io
    iswritable(io)
end
false

rm("my_file.txt")

阅读

read - 执行文件内容的读取。

Details

默认情况下,`read`以二进制模式读取文件:

read("sample1.json")

# 结论
65-element Vector{UInt8}:
 0x7b
 0x0a
 0x20
 0x20
 0x20
    ⋮

为避免表示为字节数组,建议使用表示参数。例如,"read "函数可以接受多个参数,包括文件内容应转换成的数据类型(我们使用 String):

read("sample1.json", String) # 读取sample1文件的内容。json并将其作为字符串返回

# 结论
"{\n    \"fruit\": \"Apple\",\n    \"size\": \"Large\",\n    \"color\": \"Red\"\n}"

您可以使用 Char 参数从文件中读取第一个字符,并以 Char 格式(字符类型)返回:

read("sample1.json", Char)

# 结论
'{': ASCII/Unicode U+007B (category Ps: Punctuation, open)

该函数 read(file_name::IOStream, number_of_bytes::Integer) 最多从文件流 file_name 中读取 number_of_bytes 字节,并返回包含读取字节的数组 Vector{ UInt8 }。要从文件获取数据流,必须打开文件供读取。例如

open("sample1.json", "r") # 打开文件进行读取

# 读取结果的输出
IOStream(<file sample1.json>)

read("sample1.json", 10) # 从文件中读取前10个字节

# 结论
10-element Vector{UInt8}:
 0x7b
 0x0a
 0x20
 0x20
 0x20
 0x20
 0x22
 0x66
 0x72
 0x75
*数据流是一种数据抽象,代表字节序列。序列可以从数据源读出或写入,也可以写入数据源。例如,文本文件、网络连接、内存等。数据流还可用于从数据源读取数据(输入)或向数据源写入数据(输出)。使用:
  • flush - 将当前缓冲区中的所有记录提交到该数据流。

  • close(stream)` - 关闭 I/O 流。优先执行 flush

  • closewrite(steam)` - 禁用全双工流的半写入。优先执行 flush。将不再向基础文件写入数据。并非所有 I/O 类型都支持此功能。

你可以使用 read 函数执行 cmd 命令。例如,让我们创建 date 命令(输出当前日期和时间):

# 创建输出当前日期和时间的命令
cmd = `date`

read(cmd) # 将结果输出为字节数组

read(cmd, String) # 将结果输出为字符串
# 结论
"Thu Mar 28 07:44:58 UTC 2024\n"

read! - 从 I/O 流或文件中读取二进制数据,填充数据矩阵。

Details

read!"函数用于将数据从 I/O 流或文件读入预先分配的缓冲区或数组。它通常用于有效地用外部数据填充数组,而无需创建额外的临时数组。要从文件中获取数据流,必须打开文件供读取。例如

open("sample1.json", "r") # 打开文件进行读取

my_array = zeros(UInt8, 5) # 创建一个由5个uint8类型元素组成的数组,其中填充了零
# 结论
5-element Vector{UInt8}:
 0x00
 0x00
 0x00
 0x00
 0x00

read!("sample1.json", my_array) # 从sample1中读取数据。json并用它们填充my_array数组
# 结论
5-element Vector{UInt8}:
 0x7b
 0x0a
 0x20
 0x20
 0x20

readavailable - 从数据流中读取可用的缓冲数据。

Details

如果数据流中有尚未读取的数据,函数将返回该数据。只有在数据尚未缓冲的情况下,才会执行实际 I/O。如果缓冲区中没有数据,函数将返回一个空字节数组。

返回的数据量与实现有关,例如,可能取决于缓冲区大小的内部选择。通常应使用其他函数(如 read)来代替。
IOS=open("sample1.json", "r") # 以读取模式打开文件并将其写入IOS I/O缓冲区的内容

readavailable(IOS) # 从I/O缓冲区读取可用数据并返回

readbytes! - 从 stream 到 b 执行最多 nb 字节的读取,返回读取的字节数。

Details

函数 readbytes! 从数据流中最多读取 n 个字节并将它们写入数据数组。如果未指定 n 字节,则会读取与数组长度相等的字节数。然后返回读取的字节数。如果数据流中可用的字节数少于请求的字节数,则只读取可用的字节数。

IOS=open("sample1.json", "r") # 以读取模式打开文件并将其写入IOS I/O缓冲区的内容

buffer = Vector{UInt8}(undef, 5) # 将创建一个长度为5个元素的uint8类型的空缓冲区数组

readbytes!(IOS, buffer) # 从IOS流中读取5个字节并将它们保存到缓冲区数组中

# 结论
5 # 结果,输出一个数字,该数字指示成功读取的字节数。 由于数组由5个元素组成,因此完全成功读取。

readchomp - 以一行为单位读取完整文件,并删除文件末尾的一个换行符(如果有)。

Details

readchomp` 函数等价于 chomp(read(x,String))

write("my_file.txt", "欢迎来到恩吉。\n");

readchomp("my_file.txt")

# 结论
"欢迎来到恩吉。"

readdir - 返回目录(dir)中的名称,如果未指定,则返回当前工作目录。

Details

readdir 函数用于读取一个目录的内容。它返回一个字符串数组,每个字符串代表指定目录中文件或子目录的名称。

默认情况下,readdir 会对返回的名称列表进行排序。若要跳过名称排序,按照文件系统中列出的顺序获取名称,可以使用 readdir(dir,sort=false)

cd("/user") # 转到用户开始目录

readdir() # 返回当前目录中所有文件的名称(当前为"/user")
7-element Vector{String}:
 ".git"
 ".packages"
 ".project"
 "11.ngscript"
 "engee_commands.csv"
 "my_file.txt"
 "sample1.json"

readdir(join=true) # 将返回的名称与当前目录相结合
7-element Vector{String}:
 "/user/.git"
 "/user/.packages"
 "/user/.project"
 "/user/11.ngscript"
 "/user/engee_commands.csv"
 "/user/my_file.txt"
 "/user/sample1.json"

readdir("my_dir") # 返回my_dir目录中所有文件的名称
7-element Vector{String}:
 "RTFM-HISTORY.txt"
 "delay.html"
 "difference.pdf"
 "difference.xml"
 "littleendian.svg"
 "markdown_test.md"
 "mat.mat"

readdir("my_dir", join=true) # 将返回的名称与所选目录(my_dir)相结合
7-element Vector{String}:
 "my_dir/RTFM-HISTORY.txt"
 "my_dir/delay.html"
 "my_dir/difference.pdf"
 "my_dir/difference.xml"
 "my_dir/littleendian.svg"
 "my_dir/markdown_test.md"
 "my_dir/mat.mat"

readeach - 返回结果为 read(io, T) 的迭代对象。

Details

readeach "函数用于遍历文件或数据流的内容,对每一行或每一条数据执行指定的操作。该函数的输入是要读取的流,以及要应用于每一行或每一条数据的参数。

io = IOBuffer("欢迎来到恩吉。\n函数要删除的文本。\n") # 将创建输入/输出缓冲区

for c in readeach(io, Char) # 从流中迭代字符直到达到\n,然后完成迭代。
             c == '\n' && break
             print(c)
         end

# 结论
欢迎来到恩吉。

readline - 从给定的 I/O 流或文件中读取一行文本。

Details

从文件读取时,假定文本使用的是 UTF-8 编码。输入行以"\n "或"\r\n "结束,或以输入流结束。也可以使用 keep 参数。如果 keep 设置为 false(默认值),在返回字符串之前,这些换行结束符会被从字符串中删除。如果 keep 的值为 true,它们将作为字符串的一部分返回。

write("my_file.txt", "欢迎来到恩吉。\Ntext要被函数删除。\n");

readline("my_file.txt")
"欢迎来到恩吉。"

readline("my_file.txt", keep=true)
"欢迎来到恩吉。\n"

rm("my_file.txt") # 删除文件my_file。txt脧脗脭脴

print("Enter your name: ")

your_name = readline() # 打开用户名输入窗口。
# 输入名称,例如Engee_User
"Engee_User"

readlines - 以向量或字符串的形式读取 I/O 流或文件中的所有行。

Details

其行为类似于重复保存使用相同参数读取 readline 的结果,并将读取的行保存为向量或字符串值。

write("my_file.txt", "欢迎来到恩吉。不会被函数删除的\Ntext。\n");

readlines("my_file.txt")
# 结论
2-element Vector{String}:
 "欢迎来到恩吉。"
 "函数不会删除的文本。"

readlines("my_file.txt", keep=true)
2-element Vector{String}:
 "欢迎来到恩吉。\n"
 "函数不会删除的文本。\n"

rm("my_file.txt") # 删除文件my_file。txt脧脗脭脴

readuntil - 从 I/O 流或文件中读取字符串(直到指定的分隔符)。

Details

定界符可以是 UInt8、AbstractChar、字符串或向量。命名参数 keep 决定分隔符是否包含在结果中。假定文本使用 UTF-8 编码。

write("my_file.txt", "欢迎来到恩吉。\Ntext要被函数删除。\n")

readuntil("my_file.txt", 'L')

readuntil("my_file.txt", '.', keep = true)
  "欢迎来到恩吉。"

rm("my_file.txt")

有关 Engee 中其他文件管理功能的更多信息,请访问软件控制建模