reader_other.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // +build !appengine
  2. package maxminddb
  3. import (
  4. "os"
  5. "runtime"
  6. )
  7. // Open takes a string path to a MaxMind DB file and returns a Reader
  8. // structure or an error. The database file is opened using a memory map,
  9. // except on Google App Engine where mmap is not supported; there the database
  10. // is loaded into memory. Use the Close method on the Reader object to return
  11. // the resources to the system.
  12. func Open(file string) (*Reader, error) {
  13. mapFile, err := os.Open(file)
  14. if err != nil {
  15. return nil, err
  16. }
  17. defer func() {
  18. if rerr := mapFile.Close(); rerr != nil {
  19. err = rerr
  20. }
  21. }()
  22. stats, err := mapFile.Stat()
  23. if err != nil {
  24. return nil, err
  25. }
  26. fileSize := int(stats.Size())
  27. mmap, err := mmap(int(mapFile.Fd()), fileSize)
  28. if err != nil {
  29. return nil, err
  30. }
  31. reader, err := FromBytes(mmap)
  32. if err != nil {
  33. if err2 := munmap(mmap); err2 != nil {
  34. // failing to unmap the file is probably the more severe error
  35. return nil, err2
  36. }
  37. return nil, err
  38. }
  39. reader.hasMappedFile = true
  40. runtime.SetFinalizer(reader, (*Reader).Close)
  41. return reader, err
  42. }
  43. // Close unmaps the database file from virtual memory and returns the
  44. // resources to the system. If called on a Reader opened using FromBytes
  45. // or Open on Google App Engine, this method does nothing.
  46. func (r *Reader) Close() error {
  47. var err error
  48. if r.hasMappedFile {
  49. runtime.SetFinalizer(r, nil)
  50. r.hasMappedFile = false
  51. err = munmap(r.buffer)
  52. }
  53. r.buffer = nil
  54. return err
  55. }