Julia 文件(File)读写

Julia 文件读写完全指南(中文 + 实战)

“零成本、类型安全、高性能” —— Julia 的 I/O 系统是科学计算与大数据处理的基石


一、核心概念

类型用途
IO抽象 I/O 流
IOStream文件流
IOBuffer内存流
open()打开文件
read(), write()读写
close()关闭

二、基本文本文件读写

1. 写入文件

# 方法1:open + write + close
open("output.txt", "w") do io
    write(io, "Hello, Julia!\n")
    write(io, "第二行内容\n")
end

# 方法2:do 块自动关闭
open("output.txt", "w") do f
    println(f, "自动换行")
    print(f, "不换行")
end

2. 读取文件

# 读取全部
content = read("output.txt", String)
println(content)

# 逐行读取
open("data.txt") do f
    for line in eachline(f)
        println("行: $line")
    end
end

# 读取为数组
lines = readlines("data.txt")

三、文件模式

模式含义
"r"读(默认)
"w"写(覆盖)
"a"追加
"r+"读写(保留内容)
"w+"读写(覆盖)
"a+"读写(追加)
open("log.txt", "a") do f
    println(f, "新日志: $(now())")
end

四、二进制读写(高性能!)

# 写入二进制
open("data.bin", "w") do f
    write(f, Int32(42))
    write(f, Float64(3.14))
    write(f, [1, 2, 3, 4])  # 写入数组
end

# 读取二进制
open("data.bin", "r") do f
    x = read(f, Int32)
    y = read(f, Float64)
    arr = read!(f, Vector{Int32}(undef, 4))
    println(x, ", ", y, ", ", arr)
end

零拷贝read! 直接写入预分配数组


五、内存流 IOBuffer(超实用!)

# 字符串 ↔ 流
buf = IOBuffer()
write(buf, "Hello")
write(buf, " World!")
s = String(take!(buf))  # "Hello World!"

# 复用缓冲区
buf = IOBuffer()
for i in 1:1000
    print(buf, i, ",")
end
data = String(take!(buf))

六、文件路径操作(Filesystem

using FilePathsBase  # 可选:更强大路径操作

# 标准库
path = "data/output.txt"
dirname(path)   # "data"
basename(path)  # "output.txt"
splitext(path)  # ("data/output", ".txt")
abspath(path)   # 绝对路径
isfile(path)    # 是否存在
isdir("data")   # 是否目录

# 创建目录
mkpath("logs/2025/10")

# 遍历目录
for file in readdir("data"; join=true)
    println(file)
end

七、CSV 文件读写(推荐 CSV.jl

安装:] add CSV DataFrames

using CSV, DataFrames

# 写入 CSV
df = DataFrame(
    name = ["Alice", "Bob"],
    age = [25, 30],
    score = [95.5, 88.0]
)
CSV.write("students.csv", df)

# 读取 CSV
df2 = CSV.read("students.csv", DataFrame)
println(df2)

高级选项

CSV.read("data.csv", DataFrame;
    types = Dict(:age => Int, :score => Float64),
    dateformat = "yyyy-mm-dd",
    missingstring = "NA"
)

八、JSON 文件读写(JSON.jl

using JSON

# 写入
data = Dict(
    "name" => "Julia",
    "version" => 1.10,
    "features" => ["fast", "dynamic", "scientific"]
)
open("config.json", "w") do f
    JSON.print(f, data, 2)  # 2空格缩进
end

# 读取
config = open("config.json") do f
    JSON.parse(f)
end

九、临时文件与自动清理

using FilePathsBase

# 临时文件
mktemp() do path, io
    write(io, "临时数据")
    close(io)
    # 自动删除 path
end

# 临时目录
mktempdir() do dir
    path = p"$(dir)/data.txt"
    write(path, "内容")
    # 自动删除整个目录
end

十、文件压缩(CodecZlib

using CodecZlib

# 写入 gzip
open("data.txt.gz", "w") do f
    gz = GzipCompressorStream(f)
    write(gz, "压缩内容")
    close(gz)
end

# 读取 gzip
open("data.txt.gz", "r") do f
    gz = GzipDecompressorStream(f)
    content = read(gz, String)
    println(content)
end

十一、性能优化技巧

1. 预分配 + read!

# 快:避免动态增长
open("large.bin", "r") do f
    filesize = stat(f).size
    data = Vector{UInt8}(undef, filesize)
    read!(f, data)
end

2. 缓冲写入

open("big.txt", "w") do f
    buf = IOBuffer()
    for i in 1:1_000_000
        print(buf, i, "\n")
        if position(buf) > 1_000_000
            write(f, take!(buf))
        end
    end
    write(f, take!(buf))
end

十二、综合示例:日志系统

module Logger

using Dates

const LOG_FILE = "app.log"

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

info(msg) = log("INFO", msg)
error(msg) = log("ERROR", msg)

end

# 使用
using .Logger
info("系统启动")
error("连接失败")

十三、综合示例:二进制数据序列化

struct Point
    x::Float64
    y::Float64
end

function save_points(filename, points::Vector{Point})
    open(filename, "w") do f
        write(f, Int32(length(points)))
        for p in points
            write(f, p.x)
            write(f, p.y)
        end
    end
end

function load_points(filename)
    open(filename, "r") do f
        n = read(f, Int32)
        points = Vector{Point}(undef, n)
        for i in 1:n
            x = read(f, Float64)
            y = read(f, Float64)
            points[i] = Point(x, y)
        end
        return points
    end
end

十四、文件读写速查表

操作语法
打开open("file", "r") do f ... end
写入write(f, data)
读取read(f, String)
逐行eachline(f)
二进制read!(f, array)
关闭close(f)(do 块自动)
CSVCSV.write("file.csv", df)
JSONJSON.print(f, dict)
临时文件mktemp() do path, io ... end

十五、小练习(立即上手)

  1. 写函数 copy_file(src, dst) 高效复制文件
  2. 实现 tail -f 实时监控日志文件
  3. 将 CSV 文件转为 JSON
  4. 写一个 Config 模块支持 .ini 文件
  5. 实现二进制配置文件读写(支持版本)

答案示例

# 1. 高效复制
function copy_file(src, dst)
    open(src, "r") do in_f
        open(dst, "w") do out_f
            buf = Vector{UInt8}(undef, 1024*1024)  # 1MB
            while !eof(in_f)
                n = readbytes!(in_f, buf)
                write(out_f, @view buf[1:n])
            end
        end
    end
end

# 2. tail -f
function tail_f(filename; interval=1.0)
    open(filename, "r") do f
        seekend(f)
        while true
            if !eof(f)
                line = readline(f)
                println(line)
            end
            sleep(interval)
        end
    end
end

# 3. CSV → JSON
using CSV, DataFrames, JSON
df = CSV.read("data.csv", DataFrame)
json_data = [Dict(pairs(row)) for row in eachrow(df)]
open("data.json", "w") do f
    JSON.print(f, json_data, 2)
end

十六、常见错误与避坑

错误正确做法
open("file") 忘记关闭do
read(f) 读取大文件read! + 预分配
println(f, data) 忘记换行println 自动换行
路径拼接 "data/" * filejoinpath("data", file)
编码问题指定 encoding="UTF-8"

恭喜!你已精通 Julia 文件读写!

现在你可以:

  • 构建高性能数据管道
  • 实现日志系统、配置管理
  • 处理CSV/JSON/二进制任意格式
  • 写出零拷贝 I/O 代码

下一站推荐

主题为什么学
CSV.jl + DataFrames表格数据
Parquet.jl列式存储
JLD2.jlJulia 原生二进制
SQLite.jl嵌入式数据库
HTTP.jl网络 I/O

需要我:

  • 写一个 高性能日志轮转器
  • 实现 JLD2 序列化(保存任意对象)?
  • 构建 配置热重载系统
  • 演示 内存映射文件Mmap)?

随时告诉我!

文章已创建 2302

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部