rust-csv icon indicating copy to clipboard operation
rust-csv copied to clipboard

Noob question: writing a new record overwrites the existing csv file.

Open greweln opened this issue 3 years ago • 10 comments

Noob question please: When trying to add a new record on my existing csv file, my program overwrites the csv file instead of appending the new record. As much as I've tried, I'm kind of stuck. Can someone help me with this please? Here is my code + csv file https://github.com/greweln/rust-csv

Thank you

greweln avatar Aug 09 '21 15:08 greweln

You need to open the file in append mode: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.append

And then create the CSV reader with csv::Reader::from_reader instead of from_path.

BurntSushi avatar Aug 09 '21 15:08 BurntSushi

Thank you very much!

greweln avatar Aug 09 '21 17:08 greweln

This issue can be closed I think. I do happen to have run into the exact same problem. The docs / examples don't seem to specify anywhere how to append to a CSV (which I imagine is a common requirement). Even given that most people would know to use std::fs::OpenOptions, the docs only say don't use a io::BufWriter. Which, or what kind of writer would be a good idea then?

I can open a new issue for this docs suggestion if maintainers are interested?

Thanks for a great lib!

alextes avatar Jun 20 '22 11:06 alextes

Yeah that's a great idea. Feel free to just open a PR with your suggested edits instead of a new issue.

BurntSushi avatar Jun 20 '22 12:06 BurntSushi

@BurntSushi cool, I'll try and do that today (: The one question I'll need your help with is which writer is actually a good idea. I don't see any unbuffered writers in std 😅 . In fact, I only see LineWriter but I'm not sure that's such a good idea.

alextes avatar Jun 20 '22 12:06 alextes

I think buffering and appending to an existing file are orthogonal. If there is some existing doc that led you to think otherwise, we should fix that too.

BurntSushi avatar Jun 20 '22 12:06 BurntSushi

No that makes sense to me. It's just that this lib exposes from_path and from_writer to write to CSV correct? Can't use from_path as I want to append, leaving from_writer. The docs didn't seem to give any hint on that method except to not use BufWriter, then moving on to look what writers std offers and I find BufWriter and LineWriter ending up a bit lost and unsure whether LineWriter is a good idea. So then I ended up here to see if others had asked and gotten suggestions as to which writer to use to append to a file.

Does that make sense?

alextes avatar Jun 20 '22 12:06 alextes

Ah, I think I just figured it out. Although io offers some writers like BufWriter which implement Write, File already implements a suited unbuffered Write implementation.

My confusion was that rust has many more writer implementations than I thought, it wasn't apparent to me File was one of them. In which case, I believe the current docs are good as-is 😅 .

alextes avatar Jun 20 '22 12:06 alextes

Oh I see. The issue then is probably that the universe of writers is bigger than you think it is. You can see all of them (in std) at the bottom of this page: https://doc.rust-lang.org/std/io/trait.Write.html

Notably, it includes File. Which is probably what you want. I was confused because you mentioned OpenOptions, which is all about creating a File.

The reason why the docs say "don't use a buffer" is because the csv writer does its own buffering. It isn't a correctness issue. It's just wasteful. The "don't use a buffer" advice applies regardless of whether you're appending to an existing file or not.

BurntSushi avatar Jun 20 '22 12:06 BurntSushi

I knew about "Implements" but not about "Implementors" that's so useful! (I'm new to rust). Thanks Andrew!

Yup, you've nailed my confusion there. Thanks again.

alextes avatar Jun 20 '22 12:06 alextes