Low-level file operators like Write won't work here because OutputStreams (such as you get with OpenWrite and OpenAppend) can't have their StreamPosition set before the end of the file. In general overwriting characters in an existing file isn't terribly trivial; you can use c-functions likefile_ptr = fopen(file, "rb+")
to do this, but you're overwriting character-by-character, so if you remove a character or add one it can throw things off.
Generally you're better off creating a copy of the data, along the lines of:
replaceNthRecord[file_String, n_Integer, replaceWith_] := Module[
{readStream = OpenRead[file], writeStream = OpenWrite[file <> "temp"], temp},
Do[Write[writeStream, Read[readStream]], {n - 1}];
Write[writeStream, replaceWith]; Read[readStream];
While[temp =!= EndOfFile,
temp = Read[readStream];
If[UnsameQ[temp, EndOfFile], Write[writeStream, temp]];
]; Close /@ {readStream, writeStream}
]
Close[stream]
"file.dat"
replaceNthRecord["file.dat", 3, 99]
{"file.dat", "file.dattemp"}
Make sure that "file.dattemp" is showing what you want, and then delete the original file and replace it with the temp one:
ReadList["file.dattemp"]
{1, 2, 99, 4, 5, 6, 7, 8, 9, 10}
(then just add this to the end of the function:
CopyFile[file <> "temp", file, OverwriteTarget -> True];
DeleteFile[file <> "temp"]
Note that using ReadList
appropriately here will be more efficient than Do[Write[_,Read[_]]]
but you'll need to do a bit more work to figure out what an appropriate batch size is to do this in and make sure you stop in the right place.