Skip to content

Julia 文件读写

Julia 提供了简单而强大的文件 I/O 操作功能,支持文本文件和二进制文件的读写。

打开和关闭文件

基本文件操作

julia
# 打开文件
f = open("test.txt", "w")  # 写入模式
write(f, "Hello, Julia!")
close(f)

# 使用 do 语法(推荐,自动关闭)
open("test.txt", "w") do f
    write(f, "Hello, Julia!\n")
    write(f, "This is a test.")
end

文件模式

模式描述
"r"读取(默认)
"w"写入(覆盖)
"a"追加
"r+"读写
"w+"读写(覆盖)
"a+"读写(追加)
julia
# 读取模式
f = open("test.txt", "r")
content = read(f, String)
close(f)

# 追加模式
open("test.txt", "a") do f
    write(f, "\nAppended line.")
end

读取文件

读取整个文件

julia
# 读取为字符串
content = read("test.txt", String)
println(content)

# 读取为字节数组
bytes = read("test.txt")
println(bytes)

# 使用 open + do
content = open("test.txt") do f
    read(f, String)
end

按行读取

julia
# 读取所有行(包含换行符)
lines = readlines("test.txt")
for line in lines
    println(line)
end

# 读取所有行(不保留换行符,默认)
lines = readlines("test.txt", keep=false)

# 逐行读取(内存效率更高)
open("test.txt") do f
    for line in eachline(f)
        println(line)
    end
end

# 直接对文件使用 eachline
for line in eachline("test.txt")
    println(line)
end

读取部分内容

julia
open("test.txt") do f
    # 读取指定字节数
    chunk = read(f, 10)  # 读取10字节
    println(String(chunk))
    
    # 读取一行
    line = readline(f)
    println(line)
    
    # 读取一个字符
    c = read(f, Char)
    println(c)
end

写入文件

写入字符串

julia
# 简单写入
write("output.txt", "Hello, World!")

# 使用 open
open("output.txt", "w") do f
    write(f, "Line 1\n")
    write(f, "Line 2\n")
end

# 使用 print 和 println
open("output.txt", "w") do f
    println(f, "This is line 1")
    println(f, "This is line 2")
    print(f, "No newline at end")
end

写入多行

julia
lines = ["Apple", "Banana", "Cherry"]

# 方法1:逐行写入
open("fruits.txt", "w") do f
    for line in lines
        println(f, line)
    end
end

# 方法2:使用 join
open("fruits.txt", "w") do f
    write(f, join(lines, "\n"))
end

# 方法3:使用 writedlm
using DelimitedFiles
writedlm("fruits.txt", lines)

追加写入

julia
# 追加模式
open("log.txt", "a") do f
    println(f, "$(now()): New log entry")
end

CSV 和分隔文件

使用 DelimitedFiles

julia
using DelimitedFiles

# 写入 CSV
data = [1 2 3; 4 5 6; 7 8 9]
writedlm("data.csv", data, ',')

# 读取 CSV
data = readdlm("data.csv", ',', Int)
println(data)

# 带标题的 CSV
headers = ["A" "B" "C"]
data = [1 2 3; 4 5 6]
open("data_with_header.csv", "w") do f
    writedlm(f, headers, ',')
    writedlm(f, data, ',')
end

# 读取带标题的 CSV
content = readdlm("data_with_header.csv", ',', header=true)
data = content[1]
headers = content[2]

使用 CSV.jl(推荐)

julia
using CSV
using DataFrames

# 读取 CSV
df = CSV.read("data.csv", DataFrame)
println(df)

# 写入 CSV
CSV.write("output.csv", df)

# 带选项
df = CSV.read("data.csv", DataFrame,
    delim=',',
    header=true,
    missingstring="NA"
)

JSON 文件

julia
using JSON

# 写入 JSON
data = Dict(
    "name" => "Julia",
    "version" => 1.10,
    "features" => ["fast", "dynamic", "easy"]
)

open("data.json", "w") do f
    JSON.print(f, data, 4)  # 4是缩进
end

# 读取 JSON
data = open("data.json") do f
    JSON.parse(f)
end
println(data["name"])

# 简单读取
data = JSON.parsefile("data.json")

二进制文件

读写二进制数据

julia
# 写入二进制
arr = [1.0, 2.0, 3.0, 4.0, 5.0]
open("data.bin", "w") do f
    write(f, arr)
end

# 读取二进制
arr = zeros(Float64, 5)
open("data.bin") do f
    read!(f, arr)
end
println(arr)

# 读取特定类型
open("data.bin") do f
    values = Vector{Float64}(undef, 5)
    read!(f, values)
    println(values)
end

序列化

julia
using Serialization

# 序列化 Julia 对象
data = Dict("a" => [1, 2, 3], "b" => "hello")
serialize("data.jls", data)

# 反序列化
data = deserialize("data.jls")
println(data)

文件和目录操作

路径操作

julia
# 路径拼接
path = joinpath("folder", "subfolder", "file.txt")
println(path)

# 获取目录名
println(dirname("/home/user/file.txt"))  # /home/user

# 获取文件名
println(basename("/home/user/file.txt"))  # file.txt

# 获取扩展名
println(splitext("file.txt"))  # ("file", ".txt")

# 绝对路径
println(abspath("file.txt"))

# 当前目录
println(pwd())

# 改变目录
cd("some_directory")

文件检查

julia
# 检查文件是否存在
println(isfile("test.txt"))

# 检查目录是否存在
println(isdir("some_folder"))

# 检查路径是否存在
println(ispath("test.txt"))

# 文件大小
println(filesize("test.txt"))

# 修改时间
println(mtime("test.txt"))

目录操作

julia
# 创建目录
mkdir("new_folder")
mkpath("path/to/nested/folder")  # 创建嵌套目录

# 列出目录内容
files = readdir(".")
println(files)

# 列出目录(带完整路径)
files = readdir(".", join=true)

# 遍历目录树
for (root, dirs, files) in walkdir(".")
    for file in files
        println(joinpath(root, file))
    end
end

文件操作

julia
# 复制文件
cp("source.txt", "destination.txt")

# 移动/重命名文件
mv("old_name.txt", "new_name.txt")

# 删除文件
rm("file.txt")

# 删除目录
rm("folder", recursive=true)

# 创建临时文件
temp_path, temp_io = mktemp()
write(temp_io, "Temporary content")
close(temp_io)
println(temp_path)

# 创建临时目录
temp_dir = mktempdir()
println(temp_dir)

实用示例

配置文件读取

julia
function read_config(filename)
    config = Dict{String, String}()
    
    for line in eachline(filename)
        line = strip(line)
        # 跳过空行和注释
        isempty(line) && continue
        startswith(line, '#') && continue
        
        # 解析 key=value
        if occursin('=', line)
            key, value = split(line, '=', limit=2)
            config[strip(key)] = strip(value)
        end
    end
    
    return config
end

# config.ini:
# host=localhost
# port=8080
# debug=true

日志记录器

julia
function log_message(filename, level, message)
    open(filename, "a") do f
        timestamp = Dates.format(now(), "yyyy-mm-dd HH:MM:SS")
        println(f, "[$timestamp] [$level] $message")
    end
end

log_message("app.log", "INFO", "Application started")
log_message("app.log", "ERROR", "Something went wrong")

批量处理文件

julia
function process_all_txt_files(directory)
    for file in readdir(directory)
        if endswith(file, ".txt")
            filepath = joinpath(directory, file)
            content = read(filepath, String)
            # 处理内容
            println("处理: $file ($(length(content)) 字符)")
        end
    end
end

大文件处理

julia
function count_lines(filename)
    count = 0
    for _ in eachline(filename)
        count += 1
    end
    return count
end

function process_large_file(input, output)
    open(output, "w") do out
        for line in eachline(input)
            # 处理每行
            processed = uppercase(line)
            println(out, processed)
        end
    end
end

IO 流

字符串 IO

julia
# 写入 IOBuffer
io = IOBuffer()
print(io, "Hello, ")
print(io, "World!")
content = String(take!(io))
println(content)  # "Hello, World!"

# 从字符串读取
io = IOBuffer("Line 1\nLine 2\nLine 3")
for line in eachline(io)
    println(line)
end

管道

julia
# 读取命令输出
output = read(`ls -la`, String)
println(output)

# 写入命令
open(`sort`, "w", stdout) do io
    println(io, "banana")
    println(io, "apple")
    println(io, "cherry")
end

下一步

学习完文件读写后,请继续学习:

本站内容仅供学习和研究使用。