< 返回版块

tokyohuang123 发表于 2021-12-14 15:49

   let mut file = std::fs::File::open(listpath).unwrap();
   let mut buffer: [u8; 1024000] = [0; 1024000];
//    let mut buffer: [u8; 16] = [0; 16];
    let mut rtime = 0;

    while rtime < 10 {
        let mut size = file.read(&mut buffer).unwrap();
        println!("{:02x?}",buffer);
        rtime = rtime + 1;
    }
    }
结果就是被大量00填充了
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,

评论区

写评论
作者 tokyohuang123 2021-12-15 11:29

哈哈没注意缓冲区字节数不够 导致后面的字节是老的 现在解决了

--
👇
zhylmzr: 你用同一个缓冲区数组在循环中接受文件的读取,每一次循环都会覆盖掉上一次读取的内容

作者 tokyohuang123 2021-12-15 11:28

解决了 原来是我没注意buffer后面的数据没有被清空或者填充,最后引用固定的切片可破

use std::io::{Read, Write};
use std::fs::OpenOptions;
use std::path::Path;
use std::ffi::OsStr;
// use std::fs;


const  BUFFLEN: usize =16;

pub fn read_file_by_loop(listpath: &str) {
    let filefull = listpath.split("/");
    let names: Vec<&str> = filefull.collect();
    let extension = names.last().unwrap_or(&"none");
    let extens: Vec<&str> = extension.split(".").collect();

    let fe = extens[1..(extens.len())].join(".").to_string();
    println!("这是个{:?}文件", &fe);
    // let metadata = fs::metadata(&listpath).unwrap();
    //
    // println!("{}", metadata.len());
    let mut file = std::fs::File::open(listpath).unwrap();

    let mut buffer: [u8; BUFFLEN] = [0; BUFFLEN];
    let mut rtime = 0;
    let mut savefile = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open("foo.txt")
        .unwrap();

    while true {
        let mut size = file.read(&mut buffer).unwrap();
        println!("读取字节{}个", &size);
        println!("{:02x?}", buffer);
        rtime = rtime + 1;
        if size <BUFFLEN{
            println!("最后读取字节{}个", &size);
            savefile.write(&buffer[..size]);
            break;
        }else if size == 0 {
            break;
        }else{
            savefile.write(&buffer);
        }

    }
    println!("总共进行了{}次读写", rtime);
}

#[test]
pub fn test_loop_read() {
    read_file_by_loop("./filetypelist.txt")
}
zhylmzr 2021-12-15 11:23

你用同一个缓冲区数组在循环中接受文件的读取,每一次循环都会覆盖掉上一次读取的内容

作者 tokyohuang123 2021-12-15 08:50

谢谢 只能看元数据获取文件大小了

--
👇
uno: https://doc.rust-lang.org/std/fs/struct.Metadata.html#method.len

uno 2021-12-14 17:06

https://doc.rust-lang.org/std/fs/struct.Metadata.html#method.len

作者 tokyohuang123 2021-12-14 16:59

这是运行过程 可以发现最后复制了

    Finished test [unoptimized + debuginfo] target(s) in 0.52s
     Running target/debug/deps/webooks-54d216f5e90df6ee
这是个"txt"文件
读取字节16个
[66, 66, 64, 38, 66, 66, 3d, 6a, 70, 67, 0a, 38, 39, 35, 30, 34]
读取字节16个
[65, 34, 37, 3d, 70, 6e, 67, 0a, 34, 32, 34, 64, 3d, 62, 6d, 70]
读取字节16个
[0a, 34, 37, 34, 39, 34, 36, 33, 38, 3d, 67, 69, 66, 0a, 30, 30]
读取字节16个
[30, 30, 30, 30, 32, 30, 36, 36, 37, 34, 37, 39, 37, 30, 36, 64]
读取字节16个
[37, 30, 3d, 6d, 70, 34, 0a, 32, 65, 35, 32, 34, 64, 34, 36, 30]
读取字节16个
[30, 30, 30, 30, 30, 31, 32, 30, 30, 30, 31, 3d, 72, 6d, 76, 62]
读取字节16个
[0a, 35, 32, 34, 39, 34, 36, 34, 36, 64, 30, 37, 64, 36, 30, 30]
读取字节16个
[37, 34, 31, 35, 36, 3d, 61, 76, 69, 0a, 34, 64, 35, 34, 36, 38]
读取字节16个
[36, 34, 30, 30, 30, 30, 30, 30, 30, 36, 30, 30, 30, 31, 3d, 6d]
读取字节16个
[69, 64, 0a, 34, 39, 34, 34, 33, 33, 30, 33, 30, 30, 30, 30, 30]
读取字节16个
[30, 30, 30, 32, 31, 37, 36, 3d, 6d, 70, 33, 0a, 35, 32, 34, 39]
读取字节16个
[34, 36, 34, 36, 65, 32, 37, 38, 30, 37, 30, 30, 35, 37, 34, 31]
读取字节16个
[3d, 77, 61, 76, 0a, 64, 30, 63, 66, 31, 31, 65, 30, 3d, 64, 6f]
读取字节16个
[63, 0a, 35, 30, 34, 62, 30, 33, 30, 34, 31, 34, 30, 30, 30, 36]
读取字节16个
[3d, 64, 6f, 63, 78, 0a, 32, 35, 35, 30, 34, 34, 34, 36, 32, 64]
读取字节16个
[33, 31, 32, 65, 3d, 70, 64, 66, 0a, 64, 30, 63, 66, 31, 31, 65]
读取字节16个
[30, 61, 31, 62, 31, 31, 61, 65, 31, 30, 30, 30, 30, 3d, 76, 73]
读取字节16个
[64, 0a, 33, 38, 34, 32, 35, 30, 35, 33, 3d, 70, 73, 64, 0a, 33]
读取字节16个
[63, 32, 31, 34, 34, 34, 66, 3d, 68, 74, 6d, 6c, 0a, 33, 63, 32]
读取字节16个
[31, 36, 34, 36, 66, 3d, 68, 74, 6d, 0a, 30, 30, 30, 30, 30, 31]
读取字节16个
[62, 61, 32, 31, 30, 30, 30, 31, 30, 30, 30, 31, 38, 30, 3d, 6d]
读取字节16个
[70, 67, 0a, 33, 30, 32, 36, 62, 32, 37, 35, 38, 65, 36, 36, 63]
读取字节16个
[66, 31, 31, 61, 36, 64, 39, 3d, 77, 6d, 76, 0a, 34, 31, 34, 33]
读取字节16个
[33, 31, 33, 30, 3d, 64, 77, 67, 0a, 34, 38, 35, 34, 34, 64, 34]
读取字节16个
[63, 3d, 63, 73, 73, 0a, 36, 39, 36, 62, 32, 65, 37, 31, 3d, 6a]
读取字节16个
[73, 0a, 37, 62, 35, 63, 37, 32, 37, 34, 3d, 72, 74, 66, 0a, 34]
读取字节16个
[36, 37, 32, 36, 66, 36, 64, 3d, 65, 6d, 6c, 0a, 36, 44, 36, 46]
读取字节16个
[36, 46, 37, 36, 3d, 6d, 6f, 76, 0a, 46, 46, 35, 37, 35, 30, 34]
读取字节16个
[33, 3d, 77, 70, 64, 0a, 32, 31, 34, 32, 34, 34, 34, 45, 3d, 70]
读取字节16个
[73, 74, 0a, 41, 43, 39, 45, 42, 44, 38, 46, 3d, 71, 64, 66, 0a]
读取字节16个
[45, 33, 38, 32, 38, 35, 39, 36, 3d, 70, 77, 6c, 0a, 32, 45, 37]
读取字节16个
[32, 36, 31, 46, 44, 3d, 72, 61, 6d, 0a, 34, 39, 34, 39, 32, 61]
读取字节16个
[30, 30, 3d, 74, 69, 66, 0a, 43, 46, 41, 44, 31, 32, 46, 45, 43]
读取字节16个
[35, 46, 44, 37, 34, 36, 46, 3d, 64, 62, 78, 0a, 35, 33, 37, 34]
读取字节16个
[36, 31, 36, 45, 36, 34, 36, 31, 37, 32, 36, 34, 32, 30, 34, 41]
读取字节16个
[3d, 6d, 64, 62, 0a, 32, 35, 32, 31, 35, 30, 35, 33, 32, 44, 34]
读取字节16个
[31, 36, 34, 36, 46, 36, 32, 36, 35, 3d, 70, 73, 0a, 34, 36, 34]
读取字节16个
[63, 35, 36, 30, 31, 30, 35, 30, 30, 30, 30, 30, 30, 30, 39, 30]
读取字节16个
[30, 3d, 66, 6c, 76, 0a, 35, 30, 34, 62, 30, 33, 30, 34, 31, 34]
读取字节16个
[30, 30, 30, 3d, 7a, 69, 70, 0a, 35, 32, 36, 31, 37, 32, 32, 31]
读取字节16个
[31, 61, 30, 37, 30, 30, 63, 66, 39, 30, 37, 33, 3d, 72, 61, 72]
读取字节16个
[0a, 35, 30, 34, 62, 30, 33, 30, 34, 30, 61, 30, 30, 30, 30, 30]
读取字节16个
[30, 30, 30, 30, 30, 3d, 6a, 61, 72, 0a, 34, 64, 36, 31, 36, 65]
读取字节16个
[36, 39, 36, 36, 36, 35, 37, 33, 37, 34, 32, 64, 35, 36, 3d, 6d]
读取字节16个
[66, 0a, 33, 63, 33, 66, 37, 38, 36, 64, 36, 63, 32, 30, 37, 36]
读取字节16个
[36, 35, 37, 32, 37, 33, 3d, 78, 6d, 6c, 0a, 31, 66, 38, 62, 30]
读取字节16个
[38, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 3d]
读取字节16个
[67, 7a, 0a, 34, 39, 35, 34, 35, 33, 34, 36, 30, 33, 30, 30, 30]
读取字节16个
[30, 30, 30, 36, 30, 30, 30, 3d, 63, 68, 6d, 0a, 64, 30, 63, 66]
读取字节16个
[31, 31, 65, 30, 61, 31, 62, 31, 31, 61, 65, 31, 30, 30, 30, 30]
读取字节5个
[3d, 77, 70, 73, 0a, 31, 62, 31, 31, 61, 65, 31, 30, 30, 30, 30]
读取字节0个
[3d, 77, 70, 73, 0a, 31, 62, 31, 31, 61, 65, 31, 30, 30, 30, 30]
总共进行了52次读写

而生成的文件最后也是不一样的 这是原文件的最后


1f8b0800000000000000=gz
49545346030000006000=chm
d0cf11e0a1b11ae10000=wps

生成的文件最后

1f8b0800000000000000=gz
49545346030000006000=chm
d0cf11e0a1b11ae10000=wps
1b11ae10000=wps
1b11ae10000

复制字节了

--
👇
Pikachu: 请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

作者 tokyohuang123 2021-12-14 16:54

我试了下不能用0来判断 代码如下

use std::io::{Read, Write};
use std::fs::OpenOptions;
use std::path::Path;
use std::ffi::OsStr;


pub fn read_file_by_loop(listpath: &str) {
    let filefull = listpath.split("/");
    let names: Vec<&str> = filefull.collect();
    let extension = names.last().unwrap_or(&"none");
    let extens: Vec<&str> = extension.split(".").collect();

    let fe = extens[1..(extens.len())].join(".").to_string();
    println!("这是个{:?}文件", &fe);
    let mut file = std::fs::File::open(listpath).unwrap();
    let mut buffer: [u8; 16] = [0; 16];
    let mut rtime = 0;
    let mut savefile = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open("foo.txt")
        .unwrap();

    while true {
        let mut size = file.read(&mut buffer).unwrap();
        savefile.write(&buffer);
        println!("读取字节{}个", &size);
        println!("{:02x?}", buffer);
        rtime = rtime + 1;
        if size == 0 {
            break;
        }
    }
    println!("总共进行了{}次读写", rtime)
}

#[test]
pub fn test_loop_read() {
    read_file_by_loop("./filetypelist.txt")
}





--
👇
tokyohuang123: 谢谢。我去看看

--
👇
Pikachu: 请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

Bai-Jinlin 2021-12-14 16:49

文件就是返回0就是结尾,你好奇自己看看read_to_end的实现不就好了

--
👇
tokyohuang123: 它好像说这个判断方法是不能保证到末尾的

/// 从这个源拉取一些字节到指定的缓冲区,返回
    /// 读取了多少字节。
    ///
    /// 该函数不提供是否阻塞的任何保证
    /// 等待数据,但如果一个对象需要阻塞读取并且不能,
    /// 它通常会通过 [`Err`] 返回值发出信号。
    ///
    /// 如果这个方法的返回值是[`Ok(n)`],那么实现必须
    /// 保证`0 <= n <= buf.len()`。非零的 `n` 值表示
    /// 缓冲区`buf` 已经用`n` 字节的数据填充了这个
    /// 来源。如果 `n` 是 `0`,那么它可以表示以下两种情况之一:
    ///
    /// 1. 此阅读器已到达其“文件结尾”并且可能不再
    /// 能够产生字节。请注意,这并不意味着
    /// 阅读器将*总是*不再能够产生字节。举个例子,
    /// 在 Linux 上,这个方法会为一个 [`TcpStream`] 调用 `recv` 系统调用,
    /// 返回零表示连接已正确关闭。尽管
    /// 对于[`File`],有可能到达文件末尾并得到零作为结果,
    /// 但如果更多的数据被附加到文件中,以后对 `read` 的调用将返回
    /// 更多数据。
    /// 2. 指定的缓冲区长度为 0 字节。
    ///
    /// 如果返回值`n`小于缓冲区大小,则不会出错,
    /// 即使读者还没有到达流的末尾。
    /// 这可能会发生,例如因为现在实际可用的字节较少
    ///(例如接近文件尾)或因为 read() 被信号中断。
    ///
    /// 因为这个特性可以安全地实现,调用者不能依赖 `n <= buf.len()` 来保证安全。
    /// 当使用 `unsafe` 函数访问读取字节时需要格外小心。
    /// 调用者必须确保没有未经检查的越界访问是可能的,即使
    /// `n > buf.len()`。
    ///
    /// 不保证`buf`的内容,当这个
    /// 函数被调用,实现不能依赖于任何属性
    /// `buf` 的内容为真。建议*实现*
    /// 只将数据写入 `buf` 而不是读取其内容。
    ///
    /// 但是,相应地,此方法的*调用者* 不能承担任何保证
    /// 关于实现如何使用`buf`。特性是安全的,
    /// 因此,应该写入缓冲区的代码也可能会读取
    /// 从中。你有责任确保 `buf` 被初始化
    /// 在调用 `read` 之前。使用未初始化的 `buf`(那种类型的)调用 `read`
    /// 通过 [`MaybeUninit<T>`]) 获取是不安全的,并且可能导致未定义的行为。

--
👇
Pikachu: 请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

作者 tokyohuang123 2021-12-14 16:17

它好像说这个判断方法是不能保证到末尾的

/// 从这个源拉取一些字节到指定的缓冲区,返回
    /// 读取了多少字节。
    ///
    /// 该函数不提供是否阻塞的任何保证
    /// 等待数据,但如果一个对象需要阻塞读取并且不能,
    /// 它通常会通过 [`Err`] 返回值发出信号。
    ///
    /// 如果这个方法的返回值是[`Ok(n)`],那么实现必须
    /// 保证`0 <= n <= buf.len()`。非零的 `n` 值表示
    /// 缓冲区`buf` 已经用`n` 字节的数据填充了这个
    /// 来源。如果 `n` 是 `0`,那么它可以表示以下两种情况之一:
    ///
    /// 1. 此阅读器已到达其“文件结尾”并且可能不再
    /// 能够产生字节。请注意,这并不意味着
    /// 阅读器将*总是*不再能够产生字节。举个例子,
    /// 在 Linux 上,这个方法会为一个 [`TcpStream`] 调用 `recv` 系统调用,
    /// 返回零表示连接已正确关闭。尽管
    /// 对于[`File`],有可能到达文件末尾并得到零作为结果,
    /// 但如果更多的数据被附加到文件中,以后对 `read` 的调用将返回
    /// 更多数据。
    /// 2. 指定的缓冲区长度为 0 字节。
    ///
    /// 如果返回值`n`小于缓冲区大小,则不会出错,
    /// 即使读者还没有到达流的末尾。
    /// 这可能会发生,例如因为现在实际可用的字节较少
    ///(例如接近文件尾)或因为 read() 被信号中断。
    ///
    /// 因为这个特性可以安全地实现,调用者不能依赖 `n <= buf.len()` 来保证安全。
    /// 当使用 `unsafe` 函数访问读取字节时需要格外小心。
    /// 调用者必须确保没有未经检查的越界访问是可能的,即使
    /// `n > buf.len()`。
    ///
    /// 不保证`buf`的内容,当这个
    /// 函数被调用,实现不能依赖于任何属性
    /// `buf` 的内容为真。建议*实现*
    /// 只将数据写入 `buf` 而不是读取其内容。
    ///
    /// 但是,相应地,此方法的*调用者* 不能承担任何保证
    /// 关于实现如何使用`buf`。特性是安全的,
    /// 因此,应该写入缓冲区的代码也可能会读取
    /// 从中。你有责任确保 `buf` 被初始化
    /// 在调用 `read` 之前。使用未初始化的 `buf`(那种类型的)调用 `read`
    /// 通过 [`MaybeUninit<T>`]) 获取是不安全的,并且可能导致未定义的行为。

--
👇
Pikachu: 请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

作者 tokyohuang123 2021-12-14 16:11

谢谢。我去看看

--
👇
Pikachu: 请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

Pikachu 2021-12-14 16:03

请认真阅读官方文档。 https://doc.rust-lang.org/src/std/io/mod.rs.html#632

简单摘要一下:如果read返回的size是0,说明要么到达文件末尾,要么作为参数的buf长度为0。

作者 tokyohuang123 2021-12-14 15:56

ps:不使用read_to_end的话

1 共 12 条评论, 1 页