< 返回版块

sharkLoc 发表于 2022-05-20 16:03

Tags:文件,压缩

文件打开后还在作用域内,二次使用的时候(注释所在行)为何失效呢?求助大家,感谢^_^

use std::io::{self, BufReader, BufRead};
use std::env;
use std::fs::File;
use flate2::read;

fn main() -> Result<(), io::Error> {
        let args: Vec<String> = env::args().collect();
        let file = &args[1];
    
        let fp = File::open(&file)?;
        let gz_reader = read::GzDecoder::new(&fp);

        match gz_reader.header() {
                Some(_) => { 
                    println!("gz file");
                    let reader = BufReader::new(gz_reader);
                    for each in reader.lines() {
                        if let Ok(line) = each {
                            println!("{}",line);
                        }
                    }
                },
                None => { 
                    println!("text file");
                    //let fp = File::open(file)?;  //问题就在这里,为何去掉注释就能正常输出text内文件容,否则结果为空
                    let reader = BufReader::new(&fp);
                    for each in reader.lines() {
                        if let Ok(line) = each {
                            println!("{}",line);
                        }
                    }
                }
        }
        Ok(())
}

评论区

写评论
zzhaolei 2022-05-23 16:20

刚试了下,seek之后是可以读到内容的

use flate2::read;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Seek, SeekFrom};

fn main() -> Result<(), io::Error> {
    let args: Vec<String> = env::args().collect();
    let file = &args[1];

    let mut fp = File::open(&file)?;
    let _ = read::GzDecoder::new(&fp);

    println!("text file");
    let _ = fp.seek(SeekFrom::Start(0));
    let reader = BufReader::new(&fp);
    for each in reader.lines() {
        if let Ok(line) = each {
            println!("{}", line);
        }
    }
    Ok(())
}
作者 sharkLoc 2022-05-21 19:42

还是不行

--
👇
Bai-Jinlin: 这个是因为Read,Write对&File实现了,你下面seek一下应该叫没问题了。

use std::fs::File;
use std::io::Write;
fn main()->Result<(),Box<dyn std::error::Error>>{
    let file=File::create("foo.txt")?;
    (&file).write_all(b"123")?;
    Ok(())
}

--
👇
sharkLoc: 也有想过,打开文件的时候没有mut修饰,而且也只是借用,下意识认为文件指针不会有变动,我再查查资料,谢谢!

--
👇
Grobycn: 大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

Bai-Jinlin 2022-05-20 20:13

这个是因为Read,Write对&File实现了,你下面seek一下应该叫没问题了。

use std::fs::File;
use std::io::Write;
fn main()->Result<(),Box<dyn std::error::Error>>{
    let file=File::create("foo.txt")?;
    (&file).write_all(b"123")?;
    Ok(())
}

--
👇
sharkLoc: 也有想过,打开文件的时候没有mut修饰,而且也只是借用,下意识认为文件指针不会有变动,我再查查资料,谢谢!

--
👇
Grobycn: 大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

作者 sharkLoc 2022-05-20 17:30

也有想过,打开文件的时候没有mut修饰,而且也只是借用,下意识认为文件指针不会有变动,我再查查资料,谢谢!

--
👇
Grobycn: 大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

Grobycn 2022-05-20 17:13

内部可变性吧。

io 操作有 side effect 很正常,尤其还要与系统交互。

--
👇
Neutron3529: 问题是

fp没有mut啊,在rust的直觉上,这里不应该被修改啊。

这是什么神奇的feature吗?

--
👇
Grobycn: 大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

Neutron3529 2022-05-20 16:53

问题是

fp没有mut啊,在rust的直觉上,这里不应该被修改啊。

这是什么神奇的feature吗?

--
👇
Grobycn: 大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

Grobycn 2022-05-20 16:47

大概 gz_reader 读取文件的时候修改了文件的读取位置,需要重新设置成文件开头。

1 共 7 条评论, 1 页