Skip to content
This repository
tree: 71d75fb7d4
Fetching contributors…

Cannot retrieve contributors at this time

file 190 lines (172 sloc) 4.682 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
## file formats ##

const _jl_invalid_dlm = char(0xfffffffe)

function _jl_dlm_readrow(io::IO, dlm, eol::Char)
    row_string = readuntil(io, eol)
    while length(row_string)==1 && row_string[1] == eol
        row_string = readuntil(io, eol)
    end
    if dlm == _jl_invalid_dlm
        row = split(row_string)
    else
        row = split(row_string, dlm, true)
    end
    if ends_with(row[end], eol)
        row[end] = chop(row[end])
    end
    row
end

# all strings
function _jl_dlmread(a, io, dlm, nr, nc, row, eol)
    for i=1:nr
        a[i,:] = row
        if i < nr
            row = _jl_dlm_readrow(io, dlm, eol)
        end
    end
    a
end

# all numeric, with NaN for invalid data
function _jl_dlmread{T<:Number}(a::Array{T}, io, dlm, nr, nc, row, eol)
    tmp = Array(Float64,1)
    for i=1:nr
        for j=1:nc
            if float64_isvalid(row[j], tmp)
                a[i,j] = tmp[1]
            else
                a[i,j] = NaN
            end
        end
        if i < nr
            row = _jl_dlm_readrow(io, dlm, eol)
        end
    end
end

# float64 or string
_jl_dlmread(a::Array{Any}, io, dlm, nr, nc, row, eol) =
    _jl_dlmread(a, io, dlm, nr, nc, row, eol, 1, 1)
function _jl_dlmread(a::Array{Any}, io, dlm, nr, nc, row, eol, i0, j0)
    tmp = Array(Float64,1)
    j = j0
    for i=i0:nr
        while j <= nc
            el = row[j]
            if float64_isvalid(el, tmp)
                a[i,j] = tmp[1]
            else
                a[i,j] = el
            end
            j += 1
        end
        j = 1
        if i < nr
            row = _jl_dlm_readrow(io, dlm, eol)
        end
    end
    a
end

# float64 or cell depending on data
function _jl_dlmread_auto(a, io, dlm, nr, nc, row, eol)
    tmp = Array(Float64, 1)
    for i=1:nr
        for j=1:nc
            el = row[j]
            if !float64_isvalid(el, tmp)
                a = convert(Array{Any,2}, a)
                _jl_dlmread(a, io, dlm, nr, nc, row, eol, i, j)
                return a
            else
                a[i,j] = tmp[1]
            end
        end
        if i < nr
            row = _jl_dlm_readrow(io, dlm, eol)
        end
    end
    a
end

countlines(io) = countlines(io, '\n')
function countlines(filename::String, eol::Char)
    open(filename) do io
        countlines(io, eol)
    end
end
function countlines(io::IOStream, eol::Char)
    if !iswascii(eol)
        error("countlines: only ASCII line terminators supported")
    end
    a = Array(Uint8, 8192)
    nl = 0
    preceded_by_eol = true
    while !eof(io)
        fill!(a, uint8(eol))
        try
            read(io, a)
        end
        for i=1:length(a)
            if a[i] == eol
                preceded_by_eol = true
            elseif preceded_by_eol
                preceded_by_eol = false
                nl+=1
            end
        end
    end
    nl
end

function _jl_dlmread_setup(fname::String, dlm, eol)
    if length(dlm) == 0
        error("dlmread: no separator characters specified")
    end
    nr = countlines(fname,eol)
    io = open(fname)
    row = _jl_dlm_readrow(io, dlm, eol)
    nc = length(row)
    return (io, nr, nc, row)
end

dlmread(fname::String, T::Type) = dlmread(fname, _jl_invalid_dlm, T, '\n')

dlmread(fname::String, dlm, T::Type) = dlmread(fname, dlm, T, '\n')

function dlmread(fname::String, dlm, T::Type, eol::Char)
    (io, nr, nc, row) = _jl_dlmread_setup(fname, dlm, eol)
    a = Array(T, nr, nc)
    _jl_dlmread(a, io, dlm, nr, nc, row, eol)
    close(io)
    return a
end

dlmread(fname::String) = dlmread(fname, _jl_invalid_dlm, '\n')
dlmread(fname::String, dlm) = dlmread(fname, dlm, '\n')

function dlmread(fname::String, dlm, eol::Char)
    (io, nr, nc, row) = _jl_dlmread_setup(fname, dlm, eol)
    a = Array(Float64, nr, nc)
    a = _jl_dlmread_auto(a, io, dlm, nr, nc, row, eol)
    close(io)
    return a
end

csvread(io) = dlmread(io, ',')
csvread(io, T::Type) = dlmread(io, ',', T)

# todo: keyword argument for # of digits to print
function dlmwrite(io, a::Matrix, dlm::Char)
    nr, nc = size(a)
    for i = 1:nr
        for j = 1:nc
            elt = a[i,j]
            if isa(elt,FloatingPoint)
                print_shortest(io, elt)
            else
                print(io, elt)
            end
            if j < nc
                write(io, dlm)
            end
        end
        write(io, '\n')
    end
    nothing
end

dlmwrite(io, a::Vector, dlm::Char) = dlmwrite(io, reshape(a,length(a),1), dlm)

function dlmwrite(fname::String, a::Matrix, dlm::Char)
    open(fname, "w") do io
        dlmwrite(io, a, dlm)
    end
end

dlmwrite(io, a) = dlmwrite(io, a, ',')
csvwrite(io, a) = dlmwrite(io, a, ',')
Something went wrong with that request. Please try again.