A very Julian way of describing files leveraging the built-in type system. FileIO2.jl simply provides tools/patterns to register data types with Julia type system.
FileIO2.jl therefore competes with the solution found at: http://github.com/JuliaIO/FileIO.jl.
- FileIO2.jl is a more lightweight module than FileIO.jl (Should probably have been named better).
- New file/data format types do not have to be registered with the FileIO2.jl module.
- Only types of imported (used) modules are made available (including those provided with FileIO2.jl).
- No facilities to perform dynamic loading of IO module.
- No ability to auto-detect filetype by extension.
- No ability to auto-detect filetype by magic bytes.
It might be a good idea to consolidate/re-organize the FileIO.jl and FileIO2.jl modules.
- A base module could provide the base File object hierarchies and manipulation tools.
- This module should be relatively static (unchanging).
- A registration module could provide a repository of IO modules to that read/write different files.
- This module would demonstrate how to register all the PNG readers, the MP3 readers, etc.
- Users could then create a stripped-down version of the module to meet the needs of their application - thus avoiding complex dependencies.
FileIO2.jl includes simple MIME support for images. As a result, *IJulia notebook users can display IJulia-supported images with very little code:
display(File(:jpeg, "myfile.jpeg"))
Supported image formats include:
- Pixel formats:
:bmp,:png,:gif,:jpeg,:tiff - Vector formats:
:svg,:cgm,:eps,:emf
Sample code is provided under the test directory.
open: Opens a file, and read sufficient header data to return an object ofT<:AbstractReader/T<:AbstractWriter. These objects are basically higher-level versions of IO streams.read: Reads data with whatever granularity the module developper desires (ex: individualInt/String/..., a large data block, or even an entire file).read(::Type{TIO<:AbstractReader}, ::File{T<:FileIO2.DataFormat}, ...): Equivalent toloadfor user-defined reader-only state machines.read(::Type{TIO<:AbstractDataIORW}, ::File{T<:FileIO2.DataFormat}, ...): Equivalent toloadfor user-defined read/write-capable state machines.read(r::TIO<:{AbstractReader/AbstractDataIORW}, ::Type{T<:DataType}): Reads a value of typeT, usingr. Example:val = read(myreader, Float64).write: Writes data with whatever granularity the module developper desires (ex: individualInt/String/..., a large data block, or even an entire file).write(::TIO<:AbstractWriter, ::File{T<:FileIO2.DataFormat}, ...): Equivalent tosavefor user-defined writer-only state machines.write(::TIO<:AbstractDataIORW, ::File{T<:FileIO2.DataFormat}, ...): Equivalent tosavefor user-defined read/write-capable state machines.load: The simplest interface to reading in data. Performsopen/read*/closein one convenient function.- DEPRECATED Please overload the
read()function as described above. save: The simplest interface to writing data. Performsopen/write*/closein one convenient function.- DEPRECATED Please overload the
write()function as described above.
FileIO2.DataFormat: (abstract) Identifies a data format, as opposed to a file.FileIO2.DataEncoding: (abstract) Identifies the type of data encoding used. Can be used to specialize a typeT<:DataFormat.- Can use
UnknownTextEncodingto describe "generic" versions of a type. For example:const TextFmt = TextFormat{UnknownTextEncoding}definesTextFmtto represent any text data format (irrespective of the data encoding used). - TODO: Does anybody really need to specialize a
DataFormatwith a particular encoding? AbstractReader{DataFormat}: (abstract) Used to define an object for reading from a stream formatted withDataFormat.AbstractWriter{DataFormat}: (abstract) Used to define an object for writing to a stream formatted withDataFormat.AbstractDataIORW{DataFormat}: (abstract) Used to define an object for reading/writing to a stream formatted withDataFormat.File{DataFormat}: An object used to dispatch to the appropriateopen/load/save/... functions.
The simplest way to construct a File object is to call the "shorthand" method: File(::Symbol, ::String). For example:
f1 = File(:text, "myfile.txt")
f2 = File(:png, "myimage.png")
f3 = File(:html, "myfile.html")
#When html files need to be recognized as simple text files:
f3 = File(:text, "myfile.html")
This method allows different File specializations to be constructed without exporting different DataFormat type identifiers (namespace pollution).
To register a user-defined File constructor with this shorthand notation, simply add the following method declaration:
FileIO2.File(::FileIO2.Shorthand{[NEWFMTSYMBOL]}, path::String) = File{[NEWFMT<:DataFormat]}(path)
For example, the "text" format can be registered using:
FileIO2.File(::FileIO2.Shorthand{:text}, path::String) = File{FileIO2.TextFmt}(path)
file = File(:png, "myfile.png")
reader = open(file, read=true) #Default is read=true
NOTE: A module developper must have first defined a .png reader object:
type MyPNGReader <: AbstractReader{PNGFmt}; end
Base.open(r::Type{MyPNGReader}, f::File{PNGFmt}, ...) = ...
A user can therefore call open with this specific reader:
open(MyPNGReader, file, read=true)
FileIO2.jl tries to minimize the set of exported types/aliases until a better way is found for the user to import them. At the moment, exporting too much pollutes the symbol namespace - making collisions between modules highly likely.
Extensive compatibility testing of FileIO2.jl has not been performed. The module has been tested using the following environment(s):
- Linux / Julia-1.1.1 (64-bit).
The FileIO2.jl module is not yet mature. Expect significant changes.
This software is provided "as is", with no guarantee of correctness. Use at own risk.