Prerequisites

Before we begin, ensure you have the following:

  • Rust installed on your machine. You can install it from rustup.rs.
  • Basic understanding of Rust syntax and concepts.

Project Setup

  1. Create a new Rust project:
  2. Open your terminal and run the following command:

   cargo new file_tool
   cd file_tool
  1. Edit Cargo.toml:
  2. Add any dependencies if needed. For this basic tool, we will not require external libraries.

File Manipulation Basics

We will create a simple command-line interface (CLI) that accepts commands to read from, write to, and append to files. The main functions we will implement are:

  • read_file
  • write_file
  • append_to_file

Implementing the CLI

Open the src/main.rs file and replace its contents with the following code:

use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::process;

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() < 3 {
        eprintln!("Usage: {} <command> <file> [content]", args[0]);
        process::exit(1);
    }

    let command = &args[1];
    let file_path = &args[2];

    match command.as_str() {
        "read" => read_file(file_path),
        "write" => {
            if args.len() < 4 {
                eprintln!("Usage: {} write <file> <content>", args[0]);
                process::exit(1);
            }
            let content = &args[3];
            write_file(file_path, content);
        }
        "append" => {
            if args.len() < 4 {
                eprintln!("Usage: {} append <file> <content>", args[0]);
                process::exit(1);
            }
            let content = &args[3];
            append_to_file(file_path, content);
        }
        _ => {
            eprintln!("Unknown command: {}", command);
            process::exit(1);
        }
    }
}

fn read_file(file_path: &str) {
    let mut file = File::open(file_path).unwrap_or_else(|err| {
        eprintln!("Error opening file: {}", err);
        process::exit(1);
    });
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap_or_else(|err| {
        eprintln!("Error reading file: {}", err);
        process::exit(1);
    });
    println!("{}", contents);
}

fn write_file(file_path: &str, content: &str) {
    let mut file = File::create(file_path).unwrap_or_else(|err| {
        eprintln!("Error creating file: {}", err);
        process::exit(1);
    });
    file.write_all(content.as_bytes()).unwrap_or_else(|err| {
        eprintln!("Error writing to file: {}", err);
        process::exit(1);
    });
    println!("Successfully wrote to {}", file_path);
}

fn append_to_file(file_path: &str, content: &str) {
    let mut file = OpenOptions::new()
        .append(true)
        .create(true)
        .open(file_path)
        .unwrap_or_else(|err| {
            eprintln!("Error opening file for appending: {}", err);
            process::exit(1);
        });
    file.write_all(content.as_bytes()).unwrap_or_else(|err| {
        eprintln!("Error appending to file: {}", err);
        process::exit(1);
    });
    println!("Successfully appended to {}", file_path);
}

Code Explanation

  • Command-line Arguments: We use env::args() to capture command-line arguments. The first argument is the command (read, write, or append), and the second is the file path. For write and append, a third argument is the content to be added.
  • Error Handling: We utilize unwrap_or_else to handle potential errors when opening or reading files. This provides a clear error message and exits the program gracefully.
  • File Operations:
  • read_file: Opens a file and reads its contents into a string, which is then printed to the console.
  • write_file: Creates a new file or overwrites an existing one with the provided content.
  • append_to_file: Opens a file in append mode and adds new content to the end of the file.

Running the Tool

  1. To read a file:
   cargo run -- read example.txt
  1. To write to a file:
   cargo run -- write example.txt "Hello, Rust!"
  1. To append to a file:
   cargo run -- append example.txt " This is an appended line."

Conclusion

In this tutorial, you have built a simple command-line tool for file manipulation in Rust. This project has introduced you to basic file I/O operations, error handling, and command-line argument parsing. You can extend this tool by adding more features, such as file deletion or searching for text within files.

Learn more with useful resources