fs

package module
v0.0.0-...-b7b9ca4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2018 License: MIT Imports: 3 Imported by: 186

README

FAT Filesystem Library for Go

This library implements the ability to create, read, and write FAT filesystems using pure Go.

WARNING: While the implementation works (to some degree, see the limitations section below), I highly recommend you don't use this library, since it has many limitations and is generally a terrible implementation of FAT. For educational purposes, however, this library may be interesting.

In this library's current state, it is very good for reading FAT filesystems, and minimally useful for creating FAT filesystems. See the features and limitations below.

Features & Limitations

Features:

  • Format a brand new FAT filesystem on a file backed device
  • Create files and directories
  • Traverse filesystem

Limitations:

This library has several limitations. They're easily able to be overcome, but because I didn't need them for my use case, I didn't bother:

  • Files/directories cannot be deleted or renamed.
  • Files never shrink in size.
  • Deleted file/directory entries are never reclaimed, so fragmentation grows towards infinity. Eventually, your "disk" will become full even if you just create and delete a single file.
  • There are some serious corruption possibilities in error cases. Cleanup is not good.
  • Incomplete FAT32 implementation (although FAT12 and FAT16 are complete).

Usage

Here is some example usage where an existing disk image is read and a file is created in the root directory:

// Assume this file was created already with a FAT filesystem
f, err := os.OpenFile("FLOPPY.dmg", os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
	panic(err)
}
defer f.Close()

// BlockDevice backed by a file
device, err := fs.NewFileDisk(f)
if err != nil {
	panic(err)
}

filesys, err := fat.New(device)
if err != nil {
	panic(err)
}

rootDir, err := filesys.RootDir()
if err != nil {
	panic(err)
}

subEntry, err := rootDir.AddFile("HELLO_WORLD")
if err != nil {
	panic(err)
}

file, err := subEntry.File()
if err != nil {
	panic(err)
}

_, err = io.WriteString(file, "I am the contents of this file.")
if err != nil {
	panic(err)
}

Thanks

Thanks to the following resources which helped in the creation of this library:

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BlockDevice

type BlockDevice interface {
	// Closes this block device. No more methods may be called on a
	// closed device.
	Close() error

	// Len returns the number of bytes in this block device.
	Len() int64

	// SectorSize returns the size of a single sector on this device.
	SectorSize() int

	// ReadAt reads data from the block device from the given
	// offset. See io.ReaderAt for more information on this function.
	ReadAt(p []byte, off int64) (n int, err error)

	// WriteAt writes data to the block device at the given offset.
	// See io.WriterAt for more information on this function.
	WriteAt(p []byte, off int64) (n int, err error)
}

A BlockDevice is the raw device that is meant to store a filesystem.

type Directory

type Directory interface {
	Entry(name string) DirectoryEntry
	Entries() []DirectoryEntry
	AddDirectory(name string) (DirectoryEntry, error)
	AddFile(name string) (DirectoryEntry, error)
}

Directory is an entry in a filesystem that stores files.

type DirectoryEntry

type DirectoryEntry interface {
	Name() string
	IsDir() bool
	Dir() (Directory, error)
	File() (File, error)
}

DirectoryEntry represents a single entry within a directory, which can be either another Directory or a File.

type File

type File interface {
	io.Reader
	io.Writer
}

File is a single file within a filesystem.

type FileDisk

type FileDisk struct {
	// contains filtered or unexported fields
}

A FileDisk is an implementation of a BlockDevice that uses a *os.File as its backing store.

func NewFileDisk

func NewFileDisk(f *os.File) (*FileDisk, error)

NewFileDisk creates a new FileDisk from the given *os.File. The file must already be created and set the to the proper size.

func (*FileDisk) Close

func (f *FileDisk) Close() error

func (*FileDisk) Len

func (f *FileDisk) Len() int64

func (*FileDisk) ReadAt

func (f *FileDisk) ReadAt(p []byte, off int64) (int, error)

func (*FileDisk) SectorSize

func (f *FileDisk) SectorSize() int

func (*FileDisk) WriteAt

func (f *FileDisk) WriteAt(p []byte, off int64) (int, error)

type FileSystem

type FileSystem interface {
	// RootDir returns the single root directory.
	RootDir() (Directory, error)
}

A FileSystem provides access to a tree hierarchy of directories and files.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL