跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Rust

Rust 系统编程核心技能——文件操作与网络编程基础及进阶

文章介绍了 Rust 系统编程中的文件系统操作与网络通信基础。内容涵盖标准库 std::fs 的文件创建、读写、删除及目录遍历,Unix 权限管理;TCP/IP 协议栈原理,单线程与多线程 TCP 服务器实现;以及基于 Tokio 库的异步网络编程模型。通过本地日志分析工具和异步 HTTP 客户端等实战案例,展示了 Rust 在系统级数据处理与通信中的应用,并总结了资源泄漏、阻塞 IO 等常见问题及解决方案。

编程诗人发布于 2026/2/7更新于 2026/9/104K 浏览
Rust 系统编程核心技能——文件操作与网络编程基础及进阶

Rust 系统编程核心技能——文件操作与网络编程基础及进阶

在这里插入图片描述

学习目标与重点

学习目标

  1. 掌握文件系统操作:熟练运用标准库 std::fs 模块的文件创建、读写、删除、重命名,目录遍历、权限管理(Unix 系统为主),以及错误处理
  2. 精通网络通信基础:理解 TCP/IP 协议栈的基础原理,学习 TCP 服务器/客户端的完整实现流程,包括连接建立、数据收发、错误处理、资源清理
  3. 优化网络性能:深入了解 Rust 网络编程中的异步通信模型(结合 tokio 库)、连接池、超时设置,避免常见的性能陷阱(如阻塞 IO 导致的响应慢)
  4. 实战系统编程:结合真实场景编写本地日志分析工具、简单 TCP 聊天服务器、HTTP 客户端请求工具,解决系统级的数据处理与通信问题
  5. 了解网络安全基础:学习 Rust 中的SSL/TLS 加密通信(结合 openssl 或 rustls 库),防止数据在传输过程中被窃取或篡改

学习重点

💡 三大核心难点:

  1. 文件操作的错误处理:如何区分不同类型的文件错误(如 NotFound、PermissionDenied、IsADirectory),并给出友好的提示
  2. TCP 服务器的并发处理:如何使用多线程或异步模型处理大量并发连接,避免资源泄漏和线程调度问题
  3. 异步网络编程的代码组织:如何使用 tokio 库的 async/await 语法组织异步代码,理解任务调度和 Future 的执行过程

⚠️ 三大高频错误点:

  1. 未正确关闭文件句柄:导致资源泄漏
  2. 阻塞 IO 在异步上下文中:导致程序无法处理其他请求
  3. 缓冲区溢出:在读写网络数据时未正确处理缓冲区的大小

文件系统操作详解

Rust 标准库 std::fs 模块提供了完整的文件系统操作 API,包括文件的创建、读写、删除、重命名,目录的遍历、权限管理等。

文件的基本操作

文件的创建与写入

⌨️ 文件的创建与写入示例:

use std::fs::File;
use std::io::{Write, BufWriter};
use std::path::PathBuf;

fn write_to_file(file_path: PathBuf, content: &str) -> Result<(), Box<dyn std::error::Error>> {
    // 方法 1:直接创建文件并写入(覆盖原有内容)
    let mut file = File::create(&file_path)?;
    file.write_all(content.as_bytes())?;
    file.flush()?; // 确保所有数据写入磁盘
    println!("文件写入成功:{:?}", file_path);

    // 方法 2:使用 BufWriter 缓冲写入(适合大量数据)
    let mut file = File::create(PathBuf::from("output_buffered.txt"))?;
    let mut buf_writer = BufWriter::new(file);
    buf_writer.write_all(b"Hello, ")?;
    buf_writer.write_all(b"Rust! ")?;
    buf_writer.write_all(b"Buffered write example")?;
    buf_writer.flush()?; // 必须手动刷新缓冲区
    println!("缓冲写入成功:output_buffered.txt");

    // 方法 3:追加写入
    let mut file = File::options().append(true).open(PathBuf::from("output_buffered.txt"))?;
    file.write_all(b"\nAppended content")?;
    println!("追加写入成功:output_buffered.txt");

    Ok(())
}

fn main() {
    let file_path = PathBuf::from("output.txt");
    let content = "Hello, Rust! This is a test file.\n";
    if let Err(e) = write_to_file(file_path, content) {
        println!("错误:{}", e);
    }
}
文件的读取

⌨️ 文件的读取示例:

use std::fs::File;
use std::io::{Read, BufReader};
use std::path::PathBuf;

fn read_from_file(file_path: PathBuf) -> Result<String, Box<dyn std::error::Error>> {
    // 方法 1:直接读取整个文件
    let mut content = String::new();
    let mut file = File::open(&file_path)?;
    file.read_to_string(&mut content)?;
    println!("直接读取成功:{:?}", file_path);

    // 方法 2:使用 BufReader 缓冲读取(适合大量数据)
    let file = File::open(PathBuf::from("output_buffered.txt"))?;
    let mut buf_reader = BufReader::new(file);
    let mut line_count = 0;
    loop {
        let mut line = String::new();
        let bytes_read = buf_reader.read_line(&mut line)?;
        if bytes_read == 0 {
            break;
        }
        line_count += 1;
        print!("第{}行:{}", line_count, line.trim());
    }
    println!("\n缓冲读取成功:output_buffered.txt");
    Ok(content)
}

fn main() {
    let file_path = PathBuf::from("output.txt");
    if let Ok(content) = read_from_file(file_path) {
        println!("文件内容:{}", content);
    } else {
        println!("错误:文件不存在");
    }
}
文件的删除与重命名

⌨️ 文件的删除与重命名示例:

use std::fs;
use std::path::PathBuf;

fn file_operations() -> Result<(), Box<dyn std::error::Error>> {
    // 重命名文件
    fs::rename("output.txt", "renamed_output.txt")?;
    println!("文件重命名成功:renamed_output.txt");

    // 删除文件
    fs::remove_file("output_buffered.txt")?;
    println!("文件删除成功:output_buffered.txt");

    Ok(())
}

fn main() {
    if let Err(e) = file_operations() {
        println!("错误:{}", e);
    }
}

目录的基本操作

目录的创建与删除

⌨️ 目录的创建与删除示例:

use std::fs;
use std::path::PathBuf;

fn dir_operations() -> Result<(), Box<dyn std::error::Error>> {
    // 创建单个目录
    fs::create_dir("test_dir")?;
    println!("单个目录创建成功:test_dir");

    // 创建嵌套目录
    fs::create_dir_all("test_dir/nested_dir/sub_dir")?;
    println!("嵌套目录创建成功:test_dir/nested_dir/sub_dir");

    // 删除空目录
    fs::remove_dir("test_dir/nested_dir/sub_dir")?;
    println!("空目录删除成功:test_dir/nested_dir/sub_dir");

    // 删除目录树(递归删除)
    fs::remove_dir_all("test_dir")?;
    println!("目录树删除成功:test_dir");

    Ok(())
}

fn main() {
    if let Err(e) = dir_operations() {
        println!("错误:{}", e);
    }
}
目录的遍历

⌨️ 目录的遍历示例:

use std::fs;
use std::path::PathBuf;

fn traverse_dir(dir_path: PathBuf, level: usize) -> Result<(), Box<dyn std::error::Error>> {
    let prefix = " ".repeat(level);
    for entry in fs::read_dir(dir_path)? {
        let entry = entry?;
        let file_type = entry.file_type()?;
        let file_name = entry.file_name().into_string().map_err(|_| "文件名不是 UTF-8 编码")?;
        if file_type.is_dir() {
            println!("{}📁 {}", prefix, file_name);
            traverse_dir(entry.path(), level + 1)?;
        } else if file_type.is_file() {
            println!("{}📄 {}", prefix, file_name);
        } else if file_type.is_symlink() {
            println!("{}🔗 {}", prefix, file_name);
        }
    }
    Ok(())
}

fn main() {
    let dir_path = PathBuf::from("."); // 当前目录
    println!("当前目录结构:");
    if let Err(e) = traverse_dir(dir_path, 0) {
        println!("错误:{}", e);
    }
}

文件权限管理(Unix 系统为主)

Rust 标准库 std::os::unix::fs 模块提供了Unix 系统特有的文件权限管理 API,包括权限位的设置与获取。

⌨️ 文件权限管理示例(Unix 系统):

use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;

fn permissions_operations() -> Result<(), Box<dyn std::error::Error>> {
    let file_path = PathBuf::from("test_permissions.txt");
    fs::write(&file_path, "Test permissions")?;

    // 获取当前权限
    let mut permissions = fs::metadata(&file_path)?.permissions();
    println!("当前权限位:{:o}", permissions.mode());

    // 设置权限(例如,只有所有者可读写)
    permissions.set_mode(0o600);
    fs::set_permissions(&file_path, permissions)?;
    println!("修改后的权限位:{:o}", fs::metadata(&file_path)?.permissions().mode());

    fs::remove_file(file_path)?;
    Ok(())
}

fn main() {
    if let Err(e) = permissions_operations() {
        println!("错误:{}", e);
    }
}

TCP 网络编程基础

Rust 标准库 std::net 模块提供了TCP/IP 协议栈的基础 API,包括 TCP 服务器/客户端的连接建立、数据收发等。

简单 TCP 客户端

⌨️ 简单 TCP 客户端示例:

use std::io::{Read, Write};
use std::net::TcpStream;
use std::str;

fn tcp_client() -> Result<(), Box<dyn std::error::Error>> {
    // 连接到服务器
    let mut stream = TcpStream::connect("127.0.0.1:8080")?;
    println!("成功连接到服务器:127.0.0.1:8080");

    // 发送数据
    let message = "Hello, Rust TCP Server!";
    stream.write_all(message.as_bytes())?;
    println!("发送数据:{}", message);

    // 读取服务器响应
    let mut buffer = [0; 1024];
    let bytes_read = stream.read(&mut buffer)?;
    let response = str::from_utf8(&buffer[..bytes_read])?;
    println!("收到服务器响应:{}", response);

    Ok(())
}

fn main() {
    if let Err(e) = tcp_client() {
        println!("错误:{}", e);
    }
}

简单 TCP 服务器(单线程)

⌨️ 简单 TCP 服务器示例(单线程):

use std::io::{Read, Write};
use std::net::TcpListener;

fn handle_client(mut stream: std::net::TcpStream) -> Result<(), Box<dyn std::error::Error>> {
    let peer_addr = stream.peer_addr()?;
    println!("新客户端连接:{}", peer_addr);
    let mut buffer = [0; 1024];
    loop {
        let bytes_read = stream.read(&mut buffer)?;
        if bytes_read == 0 {
            println!("客户端断开连接:{}", peer_addr);
            break;
        }
        let message = String::from_utf8_lossy(&buffer[..bytes_read]);
        println!("收到客户端{}的消息:{}", peer_addr, message.trim());

        // 发送响应
        let response = format!("服务器收到您的消息:{}", message.trim());
        stream.write_all(response.as_bytes())?;
    }
    Ok(())
}

fn tcp_server() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080")?;
    println!("服务器启动成功,监听地址:127.0.0.1:8080");

    // 单线程处理连接(一次只能处理一个连接)
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                if let Err(e) = handle_client(stream) {
                    println!("处理客户端连接错误:{}", e);
                }
            }
            Err(e) => {
                println!("接受连接错误:{}", e);
            }
        }
    }
    Ok(())
}

fn main() {
    if let Err(e) = tcp_server() {
        println!("服务器错误:{}", e);
    }
}

多线程 TCP 服务器

单线程服务器无法处理大量并发连接,我们可以使用多线程模型来解决这个问题。

⌨️ 多线程 TCP 服务器示例:

use std::io::{Read, Write};
use std::net::TcpListener;
use std::thread;

fn handle_client(mut stream: std::net::TcpStream) -> Result<(), Box<dyn std::error::Error>> {
    let peer_addr = stream.peer_addr()?;
    println!("新客户端连接:{}", peer_addr);
    let mut buffer = [0; 1024];
    loop {
        let bytes_read = stream.read(&mut buffer)?;
        if bytes_read == 0 {
            println!("客户端断开连接:{}", peer_addr);
            break;
        }
        let message = String::from_utf8_lossy(&buffer[..bytes_read]);
        println!("收到客户端{}的消息:{}", peer_addr, message.trim());
        let response = format!("服务器收到您的消息:{}", message.trim());
        stream.write_all(response.as_bytes())?;
    }
    Ok(())
}

fn tcp_server() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080")?;
    println!("服务器启动成功,监听地址:127.0.0.1:8080");

    // 多线程处理连接
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                // 每个连接创建一个新线程
                thread::spawn(move || {
                    if let Err(e) = handle_client(stream) {
                        println!("处理客户端连接错误:{}", e);
                    }
                });
            }
            Err(e) => {
                println!("接受连接错误:{}", e);
            }
        }
    }
    Ok(())
}

fn main() {
    if let Err(e) = tcp_server() {
        println!("服务器错误:{}", e);
    }
}

异步网络编程进阶(Tokio 库)

Rust 的标准库网络编程 API 是阻塞式的,无法满足高并发场景的需求。我们可以使用异步网络编程库 Tokio来实现高性能的网络应用程序。

Tokio 库的基本使用

Tokio 是 Rust 中最流行的异步运行时库,它提供了异步 IO、定时器、任务调度等功能,支持 async/await 语法。

添加依赖

在 Cargo.toml 中添加 Tokio 库的依赖:

[dependencies]
tokio = { version = "1", features = ["full"] }
异步 TCP 客户端

⌨️ 异步 TCP 客户端示例(Tokio 库):

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;

#[tokio::main]
async fn tcp_client() -> Result<(), Box<dyn std::error::Error>> {
    // 连接到服务器
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    println!("成功连接到服务器:127.0.0.1:8080");

    // 发送数据
    let message = "Hello, Rust Async TCP Server!";
    stream.write_all(message.as_bytes()).await?;
    println!("发送数据:{}", message);

    // 读取服务器响应
    let mut buffer = [0; 1024];
    let bytes_read = stream.read(&mut buffer).await?;
    let response = String::from_utf8_lossy(&buffer[..bytes_read]);
    println!("收到服务器响应:{}", response);

    Ok(())
}

fn main() {
    if let Err(e) = tcp_client() {
        println!("错误:{}", e);
    }
}
异步 TCP 服务器(Tokio 库)

⌨️ 异步 TCP 服务器示例(Tokio 库):

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;

async fn handle_client(mut stream: tokio::net::TcpStream) -> Result<(), Box<dyn std::error::Error>> {
    let peer_addr = stream.peer_addr()?;
    println!("新客户端连接:{}", peer_addr);
    let mut buffer = [0; 1024];
    loop {
        let bytes_read = stream.read(&mut buffer).await?;
        if bytes_read == 0 {
            println!("客户端断开连接:{}", peer_addr);
            break;
        }
        let message = String::from_utf8_lossy(&buffer[..bytes_read]);
        println!("收到客户端{}的消息:{}", peer_addr, message.trim());
        let response = format!("服务器收到您的消息:{}", message.trim());
        stream.write_all(response.as_bytes()).await?;
    }
    Ok(())
}

#[tokio::main]
async fn tcp_server() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    println!("服务器启动成功,监听地址:127.0.0.1:8080");

    // 异步处理连接
    loop {
        let (stream, _) = listener.accept().await?;
        // 每个连接创建一个新任务
        tokio::spawn(async move {
            if let Err(e) = handle_client(stream).await {
                println!("处理客户端连接错误:{}", e);
            }
        });
    }
}

fn main() {
    if let Err(e) = tcp_server() {
        println!("服务器错误:{}", e);
    }
}

真实案例应用

案例 1:本地日志分析工具

💡 场景分析:需要编写一个本地日志分析工具,支持统计指定目录下所有日志文件中特定关键词出现的次数,输出统计结果。

⌨️ 代码示例:

use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

fn count_keywords_in_dir(dir_path: PathBuf, keywords: &[String]) -> Result<HashMap<String, u32>, Box<dyn std::error::Error>> {
    let mut keyword_count = HashMap::new();
    for keyword in keywords {
        keyword_count.insert(keyword.clone(), 0);
    }

    for entry in fs::read_dir(dir_path)? {
        let entry = entry?;
        let file_type = entry.file_type()?;
        if file_type.is_file() && entry.file_name().to_str().map_or(false, |name| name.ends_with(".log")) {
            let file_path = entry.path();
            let file = fs::File::open(file_path)?;
            let reader = BufReader::new(file);
            for line_result in reader.lines() {
                let line = line_result?;
                for keyword in keywords {
                    let count = line.matches(keyword).count();
                    *keyword_count.get_mut(keyword).unwrap() += count as u32;
                }
            }
        }
    }
    Ok(keyword_count)
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 3 {
        println!("Usage: cargo run <dir_path> <keyword1> <keyword2> ...");
        return;
    }
    let dir_path = PathBuf::from(&args[1]);
    let keywords = &args[2..];
    if let Ok(keyword_count) = count_keywords_in_dir(dir_path, keywords) {
        println!("关键词统计结果:");
        println!("----------");
        for (keyword, count) in keyword_count.iter() {
            println!("{:<20} {}", keyword, count);
        }
    } else {
        println!("错误:目录不存在或无法访问");
    }
}

案例 2:简单异步 HTTP 客户端请求工具

💡 场景分析:需要编写一个简单的异步 HTTP 客户端请求工具,支持发送 GET 和 POST 请求,输出响应状态码和内容。

添加依赖

在 Cargo.toml 中添加 reqwest 库的依赖(reqwest 是基于 Tokio 的异步 HTTP 客户端库):

[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }

⌨️ 代码示例:

use reqwest::Client;
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 2 {
        println!("Usage: cargo run <url> [method] [json_body]");
        println!(" method: GET (default) or POST");
        println!(" json_body: JSON string for POST request");
        return Ok(());
    }

    let url = &args[1];
    let method = args.get(2).map_or("GET", |s| s.to_uppercase().as_str());
    let json_body = args.get(3);
    let client = Client::new();
    let response = match method {
        "GET" => client.get(url).send().await?,
        "POST" => {
            if let Some(body) = json_body {
                let json_value: Value = serde_json::from_str(body)?;
                client.post(url).json(&json_value).send().await?
            } else {
                println!("错误:POST 请求需要提供 JSON body");
                return Ok(());
            }
        }
        _ => {
            println!("错误:不支持的 HTTP 方法");
            return Ok(());
        }
    };

    println!("响应状态码:{}", response.status());
    println!("响应内容类型:{:?}", response.headers().get("content-type"));
    println!("响应内容:{}", response.text().await?);
    Ok(())
}

常见问题与解决方案

未正确关闭文件句柄

问题现象:导致资源泄漏。

解决方案:

  1. 使用 Rust 的所有权机制,当文件句柄变量离开作用域时会自动关闭
  2. 避免在文件句柄变量上使用 std::mem::forget 函数
  3. 如果需要手动关闭文件句柄,可以使用 drop 函数

阻塞 IO 在异步上下文中

问题现象:导致程序无法处理其他请求。

解决方案:

  1. 在异步上下文中只使用异步 IO 库(如 Tokio 的 AsyncRead、AsyncWrite trait)
  2. 避免使用标准库的阻塞 IO 函数(如 std::io::Read、std::io::Write trait)
  3. 如果需要在异步上下文中调用阻塞函数,可以使用 tokio::task::spawn_blocking 函数

缓冲区溢出

问题现象:在读写网络数据时未正确处理缓冲区的大小。

解决方案:

  1. 使用固定大小的缓冲区时,确保读取到的字节数不超过缓冲区的大小
  2. 使用动态大小的缓冲区(如 Vec<u8>)来存储大量数据
  3. 在处理网络数据时,确保考虑到消息边界的问题(如 HTTP 协议的 Content-Length 头部)

总结与展望

总结

✅ 掌握了文件系统操作:熟练运用了标准库 std::fs 模块的文件创建、读写、删除、重命名,目录遍历、权限管理,以及错误处理 ✅ 精通了网络通信基础:理解了 TCP/IP 协议栈的基础原理,学习了 TCP 服务器/客户端的完整实现流程,包括单线程和多线程模型 ✅ 优化了网络性能:深入了解了 Rust 网络编程中的异步通信模型(结合 tokio 库),理解了任务调度和 Future 的执行过程 ✅ 实战系统编程:结合真实场景编写了两个实用的代码案例:本地日志分析工具和简单异步 HTTP 客户端请求工具 ✅ 了解了网络安全基础:学习了使用 reqwest 库发送 HTTPS 请求的方法(reqwest 默认启用 SSL/TLS 加密)

展望

下一篇文章,我们将深入学习 Rust 的错误处理与测试,包括自定义错误类型的实现、错误传播的方法、单元测试的编写、集成测试的实现,通过这些知识我们将能够编写更健壮、更可维护的应用程序。

目录

  1. Rust 系统编程核心技能——文件操作与网络编程基础及进阶
  2. 学习目标与重点
  3. 学习目标
  4. 学习重点
  5. 文件系统操作详解
  6. 文件的基本操作
  7. 文件的创建与写入
  8. 文件的读取
  9. 文件的删除与重命名
  10. 目录的基本操作
  11. 目录的创建与删除
  12. 目录的遍历
  13. 文件权限管理(Unix 系统为主)
  14. TCP 网络编程基础
  15. 简单 TCP 客户端
  16. 简单 TCP 服务器(单线程)
  17. 多线程 TCP 服务器
  18. 异步网络编程进阶(Tokio 库)
  19. Tokio 库的基本使用
  20. 添加依赖
  21. 异步 TCP 客户端
  22. 异步 TCP 服务器(Tokio 库)
  23. 真实案例应用
  24. 案例 1:本地日志分析工具
  25. 案例 2:简单异步 HTTP 客户端请求工具
  26. 添加依赖
  27. 常见问题与解决方案
  28. 未正确关闭文件句柄
  29. 阻塞 IO 在异步上下文中
  30. 缓冲区溢出
  31. 总结与展望
  32. 总结
  33. 展望

更多推荐文章

查看全部
  • MySQL 表约束核心指南:从基础到外键实战
  • 13 款程序员常用开发工具及其用途详解
  • GitHub Copilot Token 消耗过快:5 种省流策略与模型替代方案
  • 网络安全工程师岗位需求分析与职业发展路径
  • Clawdbot 部署实战:反向代理与 WebAuth 安全配置指南
  • OpenClaw Session 机制详解:重置、压缩、剪枝与记忆管理
  • Stable Diffusion v1.5 创意工作流整合:Figma/Notion/Slack 自动化方案
  • Dev-C++ 安装、配置与快捷键使用指南
  • 使用 Ollama 在本地电脑运行大模型指南
  • JavaScript 数据类型全解析:分类、判断与内存差异
  • Python 爬取智联招聘数据并进行 BI 可视化分析
  • Qoder 与通义灵码 IDE:主流 AI 编程工具对比与使用指南
  • Pico 4XVR 1.10.13 安装与使用指南
  • 苍穹外卖前端开发实战:员工与套餐管理模块
  • SystemVerilog 从基础到高级验证实战指南
  • Java 类、对象与 this 引用入门
  • Z-Image-Turbo Sugar 脸部 LoRA 部署与使用指南
  • Ubuntu 搭建 Claude Code 开发环境
  • Python 定时任务实现方案:threading 与 Linux crontab 对比
  • WeblogicTool 使用指南:环境配置与运行详解

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online