24

How can I get an exclusive read access to a file in go? I have tried documentations from docs but I am still able to open the file in notepad and edit it. I want to deny any other process to have access to read and write while the first process has not closed it explicitly. In .NET I could do something as:

File.Open("a.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.None);

How do I do it in go?

Vishal Anand
  • 1,431
  • 1
  • 15
  • 32

1 Answers1

20

I finally found a go package that can lock a file.

Here is the repo: https://github.com/juju/fslock

go get -u github.com/juju/fslock

this package does exactly what it says

fslock provides a cross-process mutex based on file locks that works on windows and *nix platforms. fslock relies on LockFileEx on Windows and flock on *nix systems. The timeout feature uses overlapped IO on Windows, but on *nix platforms, timing out requires the use of a goroutine that will run until the lock is acquired, regardless of timeout. If you need to avoid this use of goroutines, poll TryLock in a loop.

To use this package, first, create a new lock for the lockfile

func New(filename string) *Lock

This API will create the lockfile if it already doesn't exist.

Then we can use the lockhandle to lock (or try lock) the file

func (l *Lock) Lock() error

There is also a timeout version of the above function that will try to get the lock of the file until timeout

func (l *Lock) LockWithTimeout(timeout time.Duration) error

Finally, if you are done, release the acquired lock by

func (l *Lock) Unlock() error

Very basic implementation

package main

import (
    "time"
    "fmt"
    "github.com/juju/fslock"
)

func main() {
    lock := fslock.New("../lock.txt")
    lockErr := lock.TryLock()
    if lockErr != nil {
        fmt.Println("falied to acquire lock > " + lockErr.Error())
        return
    }

    fmt.Println("got the lock")
    time.Sleep(1 * time.Minute)

    // release the lock
    lock.Unlock()
}
Vishal Anand
  • 1,431
  • 1
  • 15
  • 32
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/21244637) – Robert Oct 26 '18 at 13:14
  • 2
    Please don't delete this answer. This is written for someone who might need to do this/similar stuff in future. I have spent a lot of hrs to search this package – Vishal Anand Oct 27 '18 at 05:41
  • 2
    your package uses flock() for locking on Unix so doesn't provide OS level mandatory locking – Vorsprung Nov 05 '18 at 10:45
  • we were only looking for windows – Vishal Anand Nov 05 '18 at 12:00
  • this package is GPL licensed, so can't be used for commercial products. Any other package that you have come across? – Amit Bhaira May 14 '20 at 10:41
  • @AmitBhaira It is LGPLv3 which allows for use in commercial products. See https://choosealicense.com/licenses/lgpl-3.0/ – M. Leonhard Sep 03 '20 at 08:04
  • 1
    GPL also allows commercial use! It just needs you to distribute the whole program using the GPL code under GPL itself when publishing. With LGPL, you need to publish changes to the library under LGPL (or compatible) again when releasing the program. – xuiqzy Sep 14 '20 at 15:22
  • 3
    I see this package problematic because there hasn't been any modification to the code since 2016. If the author was Donald Knuth I'd say this is okay but apparently the Go community has some thoughts on it as well: https://go.googlesource.com/proposal/+/master/design/33974-add-public-lockedfile-pkg.md – Konrad Kleine Mar 03 '21 at 08:52
  • 1
    @KonradKleine Man you're a life saver. We've been having issues with "github.com/nightlyone/lockfile" and I'm not sure if the library is bugged or I screwed up. It's not clear what guarantees that library makes and the other couple libraries also leave me feeling a little uneasy. Glad the Go team has an official thread on it. :) – Sam Claus Aug 15 '21 at 04:21
  • 3
    Using LGPL licensed libraries in commercial closed-sourced golang projects doesn't really work, [see here](https://www.makeworld.space/2021/01/lgpl_go.html). There is an alternative to this library that is BSD-3 licensed: https://github.com/gofrs/flock – Ezequiel Muns Oct 19 '22 at 09:49