How to prepend to a file (add at the top)

妖精的绣舞 提交于 2019-11-29 13:15:37

in R there is no need to work with an extra file. You can just do :

writeLines(c(header,readLines(File)),File)

Yet, using the linux shell seems the most optimal solution, as R is not famous for performant file reading and writing. Especially not since you have to read in the complete file first.

Example :

Lines <- c(
"First line",
"Second line",
"Third line")
File <- "test.txt"
header <- "A line \nAnother line \nMore line \n\n"

writeLines(Lines,File)
readLines(File)    

writeLines(c(header,readLines(File)),File)
readLines(File)
unlink(File)

It is totally easy in the linux shell:

echo 'your additional header here' >> tempfile
cat example.tst >> tempfile
mv tempfile example
rm tempfile

In any language there is ultimately only one solution. And that is to overwrite the whole file:

contents = readAllOf("example.txt")

overwrite("example.txt", header + contents )

Either (A) Read the file in, add your header before and write back out (as Gareth suggested) ..or (B) Cache what you want write to the file somewhere and only write it all out when you've generated your header.

In C++, if you're willing to get your hands dirty, you can take the following steps.

  1. Stream the new content into temporary buffer (so you know the exact size of the new content)
  2. Resize the file (truncate(), ftruncate()) to include current size plus new size
  3. Map the whole file in
  4. memmove() the original file size to new position which is the new content size
  5. Copy the new data at position 0.

It's probably less effort to:

  1. Construct a new file and push the new content in
  2. Read the old file and push that in too
  3. Call operating system calls to move the new file to the old file

You generally can't expand a file backwards with most filesystems.

Normally, when you save a file, the existing data is completely overwritten. Even if you only change the first two lines of a 1,000,000 line file, the application will usually re-write the unchanged lines to disk when you hit save.

For most file formats, any headers are fixed size, so it's not a problem to change them.

There are also formats that are stream based; since the data is parsed from the stream and used to construct the document, it's possible for the stream to contain an instruction to insert some data at the beginning of the resulting document. These stream-based file formats are fairly complicated, though.

Using bash:

$ cat > license << EOF
> /* created on 31.3.2011 */
> /* author */
> /* other redundant information */
> EOF
$ sed -i '1i \\' example.txt
$ sed -i '1 {
>    r license
>    d }' example.txt

Don't know how to do it with one sed command (sed -i -e '1i \\' -e '1 { ... inserts after first line).

In R, following the original question:

df <- data.frame(a = runif(10), b = runif(10), c = runif(10))
txt <- "# created on 31.3.2011 \n# author \n# other redundant information"
write(txt, file = "example.txt") 
write.table(df, file = "example.txt", row.names = FALSE, append = TRUE)

The solution provided by Joris Meys does not work properly, overwrites the content, not appending the header to the Lines. A working version would be:

Lines <- c("First line", "Second line", "Third line")
File <- "test.txt"
header <- "A line \nAnother line \nMore line \n\n"
writeLines(Lines, File)
txt <- c(header, readLines(File)) 
writeLines(txt, File) # Option1
readLines(File) 

Instead of writeLines we could use too:

write(txt, File) # Option 2
cat(txt, sep="\n", File) # Option 3
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!