R represents connections as indices using plain
integers, e.g. idx <- as.integer(con)
.
The three connections standard input ("stdin"), standard output ("stdout"),
and standard error ("stderr") always exists and have indices 0, 1, and 2.
Any connection opened beyond these will get index three or greater,
depending on availability as given by base::showConnections()
.
To get the connection with a given index, use base::getConnection()
.
Unfortunately, this index representation of connections is non-robust,
e.g. there are cases where two or more 'connection' objects can end up with
the same index and if used, the written output may end up at the wrong
destination and files and database might get corrupted. This can for
instance happen if base::closeAllConnections()
is used (*).
In contrast, id <- connectionId(con)
gives an identifier that is unique
to that 'connection' object. This identifier is based on the internal
pointer address of the object. The risk for two connections in the same
R session to end up with the same pointer address is very small.
Thus, in case we ended up in a situation where two connections con1
and
con2
share the same index---as.integer(con1) == as.integer(con2)
---
they will never share the same identifier---
connectionId(con1) != connectionId(con2)
.
Here, isConnectionValid()
can be used to check which one of these
connections, if any, are valid.
(*) Note that there is no good reason for calling closeAllConnections()
If called, there is a great risk that the files get corrupted etc.
See (1) for examples and details on this problem.
If you think there is a need to use it, it is much safer to restart R
because that is guaranteed to give you a working R session with
non-clashing connections.
It might also be that closeAllConnections()
is used because
base::sys.save.image()
is called, which might happen if R is being
forced to terminate.