Merge 9c7884995225456d52a7b31f86470333c3adc053 into 7850a73d95c02840f4ab3bf8d9571b08410e5467

This commit is contained in:
Kivanc 2025-12-22 19:47:31 +05:30 committed by GitHub
commit 22a9fd6b70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 453 additions and 0 deletions

View File

@ -188,6 +188,12 @@ bin = [
{ name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" }, { name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" },
{ name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" }, { name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" },
{ name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" }, { name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" },
{ name = "file_io1", path = "../exercises/24_file_io/file_io1.rs" },
{ name = "file_io1_sol", path = "../solutions/24_file_io/file_io1.rs" },
{ name = "file_io2", path = "../exercises/24_file_io/file_io2.rs" },
{ name = "file_io2_sol", path = "../solutions/24_file_io/file_io2.rs" },
{ name = "file_io3", path = "../exercises/24_file_io/file_io3.rs" },
{ name = "file_io3_sol", path = "../solutions/24_file_io/file_io3.rs" },
] ]
[package] [package]

View File

@ -0,0 +1,16 @@
# File IO
Rust Provides several file I/O functions in the standard library. Buffered reads and writes provides better performance by reducing underlying reads.
## Further information
Here is the documentation for these functions in the standard library.
- [ReadToString](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
- [BufReader](https://doc.rust-lang.org/std/io/struct.BufReader.html)
- [BufWriter](https://doc.rust-lang.org/std/io/struct.BufWriter.html)
- [Path](https://doc.rust-lang.org/stable/std/path/struct.Path.html)
- [PathBuf](https://doc.rust-lang.org/std/path/struct.PathBuf.html)

View File

@ -0,0 +1,51 @@
use std::fs;
use std::path::Path;
const TEST_FILE_NAME: &str = "SampleTextFile.txt";
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let read_str_result = fs::read_to_string(TEST_FILE_NAME);
match read_str_result {
Ok(contents) => {
// TODO : What would be the expected text ?
assert_eq!(, contents);
}
Err(err) => {
eprintln!("File read error. {}", err);
}
}
file_cleanup()?;
Ok(())
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_FILE_NAME);
if !file_path.exists() {
fs::write(file_path, "This is the file content.")?;
} else {
println!("File already exist.");
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_FILE_NAME);
if file_path.exists() {
fs::remove_file(file_path).inspect(|_| {
println!("Test file {} deleted.", TEST_FILE_NAME);
})?;
} else {
println!(
"No cleanup necessary since {} not exist.",
file_path.display()
);
}
Ok(())
}

View File

@ -0,0 +1,75 @@
use std::fs;
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
const TEST_INPUT_FILE_NAME: &str = "MultiLineTextFile.txt";
const TEST_OUTPUT_FILE_NAME: &str = "MultiLineOutputFile.txt";
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let input_file = fs::File::open(TEST_INPUT_FILE_NAME).inspect_err(|err| {
eprintln!("{} file open error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
// TODO : How to create a new BufReader using input file
let buffered_input_file =;
let output_file = fs::File::create(TEST_OUTPUT_FILE_NAME).inspect_err(|err| {
eprintln!("{} file open error {:?}", TEST_OUTPUT_FILE_NAME, err);
})?;
let mut buffered_file_writer = BufWriter::new(output_file);
let mut line_number = 1;
for line in buffered_input_file.lines() {
let line = line.inspect_err(|err| {
eprintln!("{} line parse error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
buffered_file_writer
.write(format!("Line {} : {}\n", line_number, line).as_bytes())
.inspect_err(|err| {
eprintln!("{} line write error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
line_number += 1;
}
println!("{} : lines processed", line_number - 1);
file_cleanup()
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_INPUT_FILE_NAME);
if !file_path.exists() {
let text = "This is the first line of the text.
This is the second line.
And this is the third and the last line.";
fs::write(file_path, text).inspect_err(|err| {
eprintln!("Couldn't create the test file : {}", err);
})?;
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let file_names = vec![TEST_INPUT_FILE_NAME, TEST_OUTPUT_FILE_NAME];
for file_name in file_names {
let file_path = Path::new(file_name);
if file_path.exists() {
fs::remove_file(file_path).inspect(|_| {
println!("Test file {} removed", file_name);
})?;
} else {
println!("No cleanup necessary since {} not exist.", file_name);
}
}
Ok(())
}

View File

@ -0,0 +1,78 @@
use std::fs;
use std::io::Error;
use std::path::PathBuf;
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let mut path_buffer = PathBuf::new();
path_buffer.push("SampleFilesFolder");
path_buffer.push("MultiLineTextFile.txt");
// TODO : How to get metadata using path_buffer ?
let meta_data_result = path_buffer.
match meta_data_result {
Ok(meta_data) => {
println!("Metadata about the file : {:?}", path_buffer);
println!("File creation time {:?}", meta_data.created());
println!("File size {}", meta_data.len());
assert_eq!(meta_data.len(), 117);
println!("File permissions {:?}", meta_data.permissions());
assert!(!meta_data.permissions().readonly());
}
Err(error) => {
eprintln!("Could not get metadata. Error: {:?}", error);
}
}
file_cleanup()
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = PathBuf::from("SampleFilesFolder/MultiLineTextFile.txt");
let dir_path = match file_path.parent(){
Some(parent) => parent,
None => return Err(Error::other("Could not get parent path")),
};
if !dir_path.exists() {
fs::create_dir(dir_path).inspect_err(|x| {
eprintln!("Could not create directory: {:?}", x);
})?;
}
if !file_path.exists() {
let text = "This is the first line of the text.
This is the second line.
And this is the third and the last line.";
fs::write(&file_path, text).inspect_err(|err| {
eprintln!("Couldn't create test file: {:?}", err);
})?;
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let mut path_buffer = PathBuf::new();
path_buffer.push("SampleFilesFolder");
path_buffer.push("MultiLineTextFile.txt");
if path_buffer.exists() {
fs::remove_file(&path_buffer).inspect(|_| {
println!("Test file removed");
})?;
}
path_buffer.pop();
if path_buffer.exists() {
fs::remove_dir(&path_buffer).inspect(|_| {
println!("Test dir removed");
})?;
}
Ok(())
}

View File

@ -1200,3 +1200,29 @@ name = "as_ref_mut"
dir = "23_conversions" dir = "23_conversions"
hint = """ hint = """
Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions.""" Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""
# File IO Exercises
[[exercises]]
name = "file_io1"
dir = "24_file_io"
test = false
hint = """
Basic File Reading
"""
[[exercises]]
name = "file_io2"
dir = "24_file_io"
test = false
hint = """
Buffered Reading & Writing
"""
[[exercises]]
name = "file_io3"
dir = "24_file_io"
test = false
hint = """
Path Manipulation & Metadata
"""

View File

@ -0,0 +1,50 @@
use std::fs;
use std::path::Path;
const TEST_FILE_NAME: &str = "SampleTextFile.txt";
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let read_str_result = fs::read_to_string(TEST_FILE_NAME);
match read_str_result {
Ok(contents) => {
assert_eq!("This is the file content.", contents);
}
Err(err) => {
eprintln!("File read error. {}", err);
}
}
file_cleanup()?;
Ok(())
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_FILE_NAME);
if !file_path.exists() {
fs::write(file_path, "This is the file content.")?;
} else {
println!("File already exist.");
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_FILE_NAME);
if file_path.exists() {
fs::remove_file(file_path).inspect(|_| {
println!("Test file {} deleted.", TEST_FILE_NAME);
})?;
} else {
println!(
"No cleanup necessary since {} not exist.",
file_path.display()
);
}
Ok(())
}

View File

@ -0,0 +1,74 @@
use std::fs;
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
const TEST_INPUT_FILE_NAME: &str = "MultiLineTextFile.txt";
const TEST_OUTPUT_FILE_NAME: &str = "MultiLineOutputFile.txt";
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let input_file = fs::File::open(TEST_INPUT_FILE_NAME).inspect_err(|err| {
eprintln!("{} file open error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
let buffered_input_file = BufReader::new(input_file);
let output_file = fs::File::create(TEST_OUTPUT_FILE_NAME).inspect_err(|err| {
eprintln!("{} file open error {:?}", TEST_OUTPUT_FILE_NAME, err);
})?;
let mut buffered_file_writer = BufWriter::new(output_file);
let mut line_number = 1;
for line in buffered_input_file.lines() {
let line = line.inspect_err(|err| {
eprintln!("{} line parse error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
buffered_file_writer
.write(format!("Line {} : {}\n", line_number, line).as_bytes())
.inspect_err(|err| {
eprintln!("{} line write error {:?}", TEST_INPUT_FILE_NAME, err);
})?;
line_number += 1;
}
println!("{} : lines processed", line_number - 1);
file_cleanup()
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = Path::new(TEST_INPUT_FILE_NAME);
if !file_path.exists() {
let text = "This is the first line of the text.
This is the second line.
And this is the third and the last line.";
fs::write(file_path, text).inspect_err(|err| {
eprintln!("Couldn't create the test file : {}", err);
})?;
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let file_names = vec![TEST_INPUT_FILE_NAME, TEST_OUTPUT_FILE_NAME];
for file_name in file_names {
let file_path = Path::new(file_name);
if file_path.exists() {
fs::remove_file(file_path).inspect(|_| {
println!("Test file {} removed", file_name);
})?;
} else {
println!("No cleanup necessary since {} not exist.", file_name);
}
}
Ok(())
}

View File

@ -0,0 +1,77 @@
use std::fs;
use std::io::Error;
use std::path::PathBuf;
fn main() -> Result<(), std::io::Error> {
create_required_files()?;
let mut path_buffer = PathBuf::new();
path_buffer.push("SampleFilesFolder");
path_buffer.push("MultiLineTextFile.txt");
let meta_data_result = path_buffer.metadata();
match meta_data_result {
Ok(meta_data) => {
println!("Metadata about the file : {:?}", path_buffer);
println!("File creation time {:?}", meta_data.created());
println!("File size {}", meta_data.len());
assert_eq!(meta_data.len(), 117);
println!("File permissions {:?}", meta_data.permissions());
assert!(!meta_data.permissions().readonly());
}
Err(error) => {
eprintln!("Could not get metadata. Error: {:?}", error);
}
}
file_cleanup()
}
fn create_required_files() -> Result<(), std::io::Error> {
let file_path = PathBuf::from("SampleFilesFolder/MultiLineTextFile.txt");
let dir_path = match file_path.parent() {
Some(parent) => parent,
None => return Err(Error::other("Could not get parent path")),
};
if !dir_path.exists() {
fs::create_dir(dir_path).inspect_err(|x| {
eprintln!("Could not create directory: {:?}", x);
})?;
}
if !file_path.exists() {
let text = "This is the first line of the text.
This is the second line.
And this is the third and the last line.";
fs::write(&file_path, text).inspect_err(|err| {
eprintln!("Couldn't create test file: {:?}", err);
})?;
}
Ok(())
}
fn file_cleanup() -> Result<(), std::io::Error> {
let mut path_buffer = PathBuf::new();
path_buffer.push("SampleFilesFolder");
path_buffer.push("MultiLineTextFile.txt");
if path_buffer.exists() {
fs::remove_file(&path_buffer).inspect(|_| {
println!("Test file removed");
})?;
}
path_buffer.pop();
if path_buffer.exists() {
fs::remove_dir(&path_buffer).inspect(|_| {
println!("Test dir removed");
})?;
}
Ok(())
}