tmontaigu / dbase-rs

Rust library to read & write dBase files.
MIT License
29 stars 30 forks source link

Getting 'UnexpectedEOF' error when trying to instantiate a Reader #40

Closed PhilVince96 closed 2 years ago

PhilVince96 commented 2 years ago

Hi,

my program does create a new database (.dbf file) with some records and then tries to read them afterwards. The first part works. When I open the created .dbf in Excel I can see all written records, but the program fails when it tries to read the file which it created. I ran the example print-content.rs with tests/data/line.dbf and tests/data/stations.dbf and it worked just fine. I think maybe the problem lies within the creation of the file, although Excel can handle the created file. Maybe somebody can help me.

Thanks! :)

Error: Screenshot 2022-10-09 at 11 02 53

Code:

use dbase::{Error, FieldName, FieldValue, Reader, Record, TableWriterBuilder};
use std::convert::TryFrom;
use std::path::Path;

fn main() -> Result<(), Error> {
    // Create Path
    let path = Path::new("./db/dbase.dbf");

    // Build a TableWriter with a creation of a new DBF
    let mut writer = TableWriterBuilder::new()
        .add_character_field(FieldName::try_from("FirstName").unwrap(), 50)
        .add_character_field(FieldName::try_from("LastName").unwrap(), 50)
        // .add_integer_field(FieldName::try_from("Age").unwrap())
        .build_with_file_dest(path)?;

    // Create record
    let mut record = Record::default();
    let _result = record.insert(
        "FirstName".to_owned(),
        FieldValue::Character(Some("Sven".to_owned())),
    );

    let _result = record.insert(
        "LastName".to_owned(),
        FieldValue::Character(Some("Ebert".to_owned())),
    );

    // let _result = record.insert("Age".to_owned(), FieldValue::Integer(62));

    // Write record
    writer.write_record(&record)?;

    // Read records with `read()`
    /*let records = read(path)?;
        for record in records {
            for (name, value) in record {
                println!("{} -> {:?}", name, value);
                match value {
                    FieldValue::Character(Some(string)) => println!("Got String {}", string),
                    FieldValue::Integer(value) => println!("Got integer value of {:?}", value),
                    _ => {}
                }
            }
        }
    */

    let mut reader = Reader::from_path(path)?; // the error happens in this line
    for record_result in reader.iter_records() {
        let record = record_result?;
        for (name, value) in record {
            println!("name: {}, value: {:?}", name, value);
        }
    }

    Ok(())
}
tmontaigu commented 2 years ago

That is because you are reading the file that the writer hasn't finished to fully write.

While the writer is 'alive' (not dropped) the file it writes to is incomplete. As when the writer is dropped it updates parts of the files with are not known until every record has been written.

You can add a drop(writer) before creating your reader and you'll see that it works

PhilVince96 commented 2 years ago

That is because you are reading the file that the writer hasn't finished to fully write.

While the writer is 'alive' (not dropped) the file it writes to is incomplete. As when the writer is dropped it updates parts of the files with are not known until every record has been written.

You can add a drop(writer) before creating your reader and you'll see that it works

Thank you very much! Good to know that. :D It works now. 👍🏻