Can I append to the top of a file with File node?

It would be very nice, but I can't seem to find a way in the node. So is it just me being bad at looking for it? :slight_smile:

No,

But a quick google should show ways of doing it on the command line that you could do with an exec node.

Yeah, I know, thanks. I just wanted to see if it could be done with the file noed.

You could look at the node, figure out how to make it work, discuses it in slack and submit a PR :slightly_smiling_face:

Probably, if I was actually able to code myself out of a brown paper bag... :blush: But I'm not, unfortunately.

Actually you can do it with the file node, no need to resort to command line.

However, a serious caveat. To do it requires reading the whole file into memory each time. That might not work depending on the size of the file and the available memory.

Read the file, Use a function or change node to add the new line to the start (or in reality add the file to the new line text), write back to the file.

Not terribly efficient and if you really need something like this, a database would almost certainly be a lot easier to deal with.

Note that command line tools may well do the same process but it is possible that they could stream the file content so that you could deal with a file larger than your available memory. Oddly enough, Microsoft PowerShell is excellent for that kind of processing.

Interesting! I actually only use it to keep track of reboots (because of loss of signal from Tellstick, RFXtrx, Z-Wave or MQTT), and that means a couple of lines every day, so I'm guessing it would take quite a long time before that becomes a problem. The problem is of course that I have no idea how to do it. The script is like this:

var d = new Date();
var hours = d.getHours();
var minutes = d.getMinutes();
var seconds = d.getSeconds();
var year = d.getFullYear();
var month = d.getMonth()+1;
if (month < 10) {
    month = '0'+ month;
}
var day = d.getDate();
if (day < 10) {
    day = '0'+ day;
}
if (hours < 10) {
    hours = '0'+ hours;
}
if (minutes < 10) {
    minutes = '0'+ minutes;
}
if (seconds < 10) {
    seconds = '0'+ seconds;
}
var global_n = year+'-'+month+'-'+day+' '+hours+':'+minutes+':'+seconds;
msg.payload = global_n + ", omstart pga. forsvunnet Z-Wave-signal";
msg.topic = 'Z-Wave-signal ute fra Z-Wave-Pi';
return msg;

And no, I didn't create that myself either... :wink: So that creates a line like this:

2019-07-01 19:05:18, omstart pga. forsvunnet Z-Wave-signal

I'm guessing it takes a lot of lines before that is a problem.

What are you doing later to the file that means you want/need to add to the top ?
You could for example add to the end - but then just list it in reverse... eg tail -r myfile.txt (if on Linux)

1 Like

Rename the existing file to a temporary file.
Make a new file and write the new line to it.
Copy the content from the temporary file line by line to the new file.
Delete the temporary file.
This approach doesn't require a lot of memory.

Just my 2 cents.

dceejay, I check when the last restart was. It's pure habit, my other stuff adds the final log line at the end. And the only Linux in this house is in the Pi's, it saves the file to a mounted share, and I do all my manual checking in Windows.

edje11, sounds like a good plan, thanks! I will see tonight if I can manage to implement it without help.... :blush:

is there any reason you need to have the newest line at the top of the file? most OS support appending to the end of a file which would save you a lot of effort.

The reason was simply that the file gets one line every day, and I'd like to see the newest line at the top.

Write the line to a new file, then read the old file and write it to the new file.

Thanks, that's some what what I ended up doing some months ago. :slight_smile: First I write the line to tempfile.txt and then I use cat:

cat logfile.txt >> tempfile.txt

Then I use file operations to delete the logfile.txt and rename the tempfile.txt to logfile.txt. I was just wondering back then if the File node could append to the top by itself.