Never thought, yesterday I asked a question about how to download files from the Internet, and after I got the answer, I found that the downloaded files were totally different from the files on the server

Complete source code:

use std::fs::File;
use std::io;

fn main() {
    let save_file_path = "temp.zip";
    let download_url = "https://github.com/Aaron009/temp_rust_web_download/raw/main/wwwroot/temp.zip";
    let resp = reqwest::blocking::get(download_url).expect("request failed");
    let body = resp.text().expect("body invalid");
    let mut out = File::create(save_file_path).expect("failed to create file");
    let mut body_bytes = body.as_bytes();
    io::copy(&mut body_bytes, &mut out).expect("failed to copy content");

    println!("download completed!");
}

I use "Beyond Comparison" to compare screenshots as follows:
a.png

As shown in the figure, it is found that the file size is different, and the file size marked in red is also different. what is the reason?

1 Like

The reason is simple - downloaded file is not a text, so, when you converted it to String, every non-Unicode characters were replaced by 0xefbfbd sequence, the so-called "replacement character". You probably want to use resp.bytes() instead of resp.text().

6 Likes

I have never seen such a simple question, so I am ashamed。

thank you very much!

My final code was changed to the following:

use std::fs::File;
use std::io;

fn main() {
    let save_file_path = "temp.zip";
    let download_url = "https://github.com/Aaron009/temp_rust_web_download/raw/main/wwwroot/temp.zip";
    let resp = reqwest::blocking::get(download_url).expect("request failed");
    let body = resp.bytes().expect("body invalid");
    let mut out = File::create(save_file_path).expect("failed to create file");
    let mut body_bytes= body.to_vec();
    io::copy(&mut &body_bytes[..], &mut out).expect("failed to copy content");

    println!("download completed!");
}

You see if it is necessary to optimize!

A few notes:

  1. The .to_vec() call is not necessary. You can do &mut &body[..] directly.
  2. Creating the file can be done through std::fs::write with std::fs::write(save_file_path, &body).
2 Likes

The code is optimized and amended as follows:

fn main() {
    let resp = reqwest::blocking::get("http://192.168.80.112:8080/encrypt.sh").expect("request failed");
    let body = resp.bytes().expect("body invalid");
    std::fs::write("./ff.sh", &body);
}

Good! I hope to be like you at an early date, and thank you very much for your help.

I have read the whole book through the official website

https://doc.rust-lang.org/book/title-page.html

Do you have a recommended way to learn Rust? How did you learn Rust? I hope to be like you.

2 Likes

Besides reading the book, I guess you should just try to actually use the language to build something, then ask questions when you get stuck.

I started looking at Rust around five years ago, but at that time it was only a bit at the time. Honestly, answering questions here has been probably my biggest source of learning things about Rust, since I get to see so many different questions from so many different parts of Rust I would not encounter on my own.

6 Likes

When I learn any language, I try to do what I want to do, then look at the problems other people have and see how they solve it. I often go to forums or Stack Overflow.

1 Like

For me, AFAIR I read the nomicon pretty quickly, too, after the book. Then looking through the standard library (docs) to know the API for common types (especially the data structures) without having to look it up helps, as well looking through the reference for deepening the understanding of the Rust language in detail. Going further, reading (some of) the documentation of some popular crates helps as well. I’m personally not so much into creating my own practical code, hence I didn’t really ask any questions myself for learning Rust; so for me reading other people’s questions (and then the answers) or perhaps even trying to answer the myself in this forum also aided with learning Rust, I would say. I do write small test programs if I’m wondering what the compiler has to say about some things, so in a playing-around-with-the-compiler kind of fashion I do write code. Another thing is: There’s this “[src]” button on every function or type in std or any crate, so clicking that just reading the implementation of something that seems interesting but not too complicated is a great learning experience, too.

On certain aspects, especially the fundamental concepts behind Rust’s type-system, low-level stuff, types with constructors and destructors, etc. was in my case aided by knowing C and C++ a bit and knowing Haskell really well; as well as some general knowledge from my computer science degrees.

And on some topics searching for specific tutorials / talks / etc. online helps, e.g. around async fn.

2 Likes

Just to add on what other people said, I've learned a lot from following This Week in Rust. When you're starting out, you'll probably learn something from most of the linked blog posts and the like. Regardless of where you're at, you'll learn about what's going on in the language from the RFCs, stablization FCPs, and so on. Version announcements/changelogs are good for this too. And if you read the github issues and PRs generally, you'll soon get a feel for who the main contributors are, or at least a feel for many team members. This can pay off later on if you come across a crate and recognize the maintainers, for example.

You can also look up the blogs of team members, forum posters, etc. once you've found some with a presentation that is a good match for your learning style. Here are a few I've learned from that come to mind offhand:

You can also read other people's questions here or on the chat platforms, and then try to solve them yourself in the playground.