Go Down

Topic: rewriting a file on a SD-card (Read 1 time) previous topic - next topic

Yamat0

Im working on this project where I need to rewrite lines in an existing textfile on a sd-card.

The data is a bunch of ints stored commaseparated. I have read that its possible to replace, but not insert. but i have not found any example over how to do this..


the data on the file looks something like this:
Code: [Select]

12345,0023,0233
67890,0023,0043
12367,0013,0002
23489,0024,0003


the first column is the "unique" number that I first search for, this part I can manage. when I have found my "line" i would like to manipulate the other two values, two values that are always between 0000 and 9999.

So the question is:
is there a way to rewrite everything on line 3. (i know the number of the byte of the first byte in that line). As you can see, the datalines are always the same lenght, so I know where to write, if there just is some command for it:)
print() writes at the end of the file? right?



PaulS

Quote
I have read that its possible to replace

Sure. If the file is open for read/write, and you have read to some point, and you start writing, the bytes that were there will be overwritten.

Quote
but not insert.

You would have to copy the rest of the data in the file to another file, and then overwrite the existing data in the first file, and then copy the second file back after writing the new data.

Using fixed length records would allow you to replace one fixed length record with another.

Quote
So the question is:
is there a way to rewrite everything on line 3.

Yes. Use position() to record the start of each record. Read until the end. Determine if it is the correct record to replace. Then, use seek() to go back to the start of the record.

Quote
print() writes at the end of the file? right?

No. print() starts writing at the current position. For a file opened in append mode, the current position is the end of the file. For a file opened in truncate mode, the current position is the start of the file. For a file opened for read and write, the current position is initially the start of the file. It changes as you read(). seek() allows you to position it wherever you like.

Yamat0

#2
Sep 21, 2013, 05:34 pm Last Edit: Sep 21, 2013, 05:37 pm by Yamat0 Reason: 1
As the files are pretty large, its more or less impossible to save parts of them to a new file as you only are allowed to have one file open at any given moment i would have to first write it all to memory, then to the new file and that will not work, But I think master PaulS has the ansver im looking for!

To Paul:
Thank you PaulS, that clarified that is possible at least..

now to code.
when doing my first "look for the right row" i have used the following:
Code: [Select]
aFile = SD.open("data.txt", FILE_READ);

But I guess that I would this if i want to both read and write files(guess that the above might be faster? or else why do you have it at all?)
In what other ways are FILE_READ and FILE_WRITE different than the fact that you can actually use print in FILE_WRITE mode?
(NOTE: saw that FILE_WRITE starts at the end of the file too. i should be able to use aFile.seek(0); to move to the front? right?)
(Will try this tonight when my children are a sleep..)

seek() and possition() is probably going to solve this riddle for me!

But I want to learn more...
You are talking about "append mode" and "truncate mode", never herd of those and never came across any examples with those within, care to explain how I could use this modes to my advantage?



PaulS

Quote
In what other ways are FILE_READ and FILE_WRITE different than the fact that you can actually use print in FILE_WRITE mode?

"Other than the fact that you can write to a file opened using FILE_WRITE" seems to gloss over the fact that FILE_WRITE means that you CAN write to the file.

Quote
guess that the above might be faster? or else why do you have it at all?

Opening the file for read and write is not slower than opening it for read only. Opening it read-only ensures that you can't actually write to it.

Quote
NOTE: saw that FILE_WRITE starts at the end of the file too.

That depends on other settings. O_TRUNC and O_APPEND position the cursor in different places.

Quote
i should be able to use aFile.seek(0); to move to the front? right?

Yes.

Quote
You are talking about "append mode" and "truncate mode", never herd of those and never came across any examples with those within, care to explain how I could use this modes to my advantage?

Look at how FILE_READ and FILE_WRITE are defined.
Code: [Select]
#define FILE_READ O_READ
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT)

You can OR on other attributes when you open the file. O_APPEND and O_TRUNC are just two of the other attributes.

SdFile.cpp contains:
Code: [Select]
/**
* Open a file or directory by name.
*
* \param[in] dirFile An open SdFat instance for the directory containing the
* file to be opened.
*
* \param[in] fileName A valid 8.3 DOS name for a file to be opened.
*
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
* OR of flags from the following list
*
* O_READ - Open for reading.
*
* O_RDONLY - Same as O_READ.
*
* O_WRITE - Open for writing.
*
* O_WRONLY - Same as O_WRITE.
*
* O_RDWR - Open for reading and writing.
*
* O_APPEND - If set, the file offset shall be set to the end of the
* file prior to each write.
*
* O_CREAT - If the file exists, this flag has no effect except as noted
* under O_EXCL below. Otherwise, the file shall be created
*
* O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
*
* O_SYNC - Call sync() after each write.  This flag should not be used with
* write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
* These functions do character at a time writes so sync() will be called
* after each byte.
*
* O_TRUNC - If the file exists and is a regular file, and the file is
* successfully opened and is not read only, its length shall be truncated to 0.
*
* \note Directory files must be opened read only.  Write and truncation is
* not allowed for directory files.
*
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
* Reasons for failure include this SdFile is already open, \a difFile is not
* a directory, \a fileName is invalid, the file does not exist
* or can't be opened in the access mode specified by oflag.
*/

Go Up