1

How do I get the current position of the cursor in an opened filestream in rust, after reading several lines?

For examples: Here I am moving the cursor 6 bytes from start. Read until 50 characters. After this I would like to get the current position of the cursor, and seek the cursor again from its position.

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

fn main() {

    let fafile: String = "temp.fa".to_string();
    let mut file = File::open(fafile).expect("Nope!");
    let seekto: u64 = 6;
    file.seek(SeekFrom::Start(seekto)); //open a file and seek 6 bytes
    let reader = BufReader::new(file);

    let mut text: String = "".to_string();

    //Stop reading after 50 characters
    for line in reader.lines(){
        let line = line.unwrap();
        text.push_str(&line);
        if text.len() > 50{ 
            break;
        }
    }

   //How do I get the current position of the cursor? and
  // Can I seek again to a new position without reopening the file? 
  //I have tried below but it doesnt work.

   //file.seek(SeekFrom::Current(6)); 

}

I have checked seek which offers to move the cursor from start, end and current but does not tell me the current position.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
PoisonAlien
  • 431
  • 4
  • 13
  • Not really. As one of the [comments](https://stackoverflow.com/questions/34878970/how-to-get-current-cursor-position-in-file#comment95244996_34889413) pointed, there is this issue with `moved value` which makes `file` no longer accessible after first seek. – PoisonAlien May 20 '20 at 11:53

1 Answers1

4

Regarding your first question, seek returns the new position after moving. So you can get the current position by seeking with an offset of 0 from the current:

let current_pos = reader.seek (SeekFrom::Current (0)).expect ("Could not get current position!");

(see also this question)

Regarding the second question, you can no longer access the file variable once you've moved it into the BufReader, but you can call seek on the reader itself:

reader.seek (SeekFrom::Current (6)).expect ("Seek failed!");

As pointed out in the comments, this only works if you haven't moved the reader, so you also need to change your reading loop to borrow reader instead of moving it:

for line in reader.by_ref().lines() {
    // ...
}
Jmb
  • 18,893
  • 2
  • 28
  • 55
  • Thanks. Unfortunately, its the same issue with `reader` variable as well. I get the same error as `value moved`. I know exact position of the strings that I want in a large text file. I need to seek from one position after another without re-opening the file for faster random access. – PoisonAlien May 20 '20 at 11:47
  • 2
    it's not the same issue: now your reader is being consumed by the `lines()` call. You can use `reader.by_ref().lines()` to avoid moving reader. – Jussi Kukkonen May 20 '20 at 11:58
  • Great. This works. – PoisonAlien May 20 '20 at 12:11