After using vim to modify the file, the :file module seems to lose contact with the file?

I encountered this phenomenon before. I didn’t study the reason in depth at the time, but avoided it in an inefficient way.

Steps to reproduce:

Open a iex, open a file through the :file module, and write content to it:

iex> {:ok, f} = :file.open "txtfile", [:read, :write, :utf8]
{:ok, #PID<0.168.0>}
iex> IO.write f, "hello"
:ok
iex> IO.read f, :all
“hello”

The above process is all normal. If an external editor such as nano or other edits the content of txtfile to hello1, we can still read the modified content:

iex> :file.position f, :bof
{:ok, 0}
iex> IO.read f, :all       
'hello1\n'

However, if you use VIM to edit and save this file, everything is abnormal.

➜  ~ vim txtfile
➜  ~ cat txtfile
hello2

As you can see, I used VIM to modify the content to hello2. Then, I tried to continue reading from the beginning in iex:

iex> :file.position f, :bof
{:ok, 0}
iex> IO.read f, :all       
'hello1\n'

Not only that, even if I use any editor to continue editing txtfile, the latest file content will not be read in iex. All this is because I have saved this file with VIM.

When edit a file using Vim, Vim actually created a new file with a new inode that points to a new location on the hard drive. After saving the file, Vim associates the original filename with the new inode, but your iex is still reading and writing the file with the old file descriptor, so you can only read the old content in iex.

5 Likes

And by the way, you can use ls -i to see the inode number, and verify what I said :upside_down_face:

1 Like

Funny thing is, if a file has a hard link to it (i.e. 2 filenames pointing to the same inode), vim does not create a new file.

$ echo hello > hello_world.txt
$ ls -i
24519754 hello_world.txt

$ vim hello_world.txt  # edit it and save
$ ls -i
24521691 hello_world.txt

$ ln hello_world.txt hello_world2.txt
$ ls -il
24521691 -rw-rw-r-- 2 me me 12 Jul 30 18:49 hello_world2.txt
24521691 -rw-rw-r-- 2 me me 12 Jul 30 18:49 hello_world.txt

$ vim hello_world.txt  # edit it and save
$ ls -il
24521691 -rw-rw-r-- 2 me me 16 Jul 30 18:52 hello_world2.txt
24521691 -rw-rw-r-- 2 me me 16 Jul 30 18:52 hello_world.txt

$ vim hello_world2.txt  # edit it and save
$ ls -il
24521691 -rw-rw-r-- 2 me me 21 Jul 30 18:53 hello_world2.txt
24521691 -rw-rw-r-- 2 me me 21 Jul 30 18:53 hello_world.txt
2 Likes

@Aetherus

Yes, it is so. Thank you for popularizing the reasons behind this. Knowing this, I might be able to find other more effective ways to be compatible with VIM’s save behavior. Thank you again. :+1: