CSV ZipFile read example broken in Julia 1.11.0

I am using 1.11.0 on a Windows machine with

(jl_FpGwGs) pkg> st
Status `C:\Users\jakez\AppData\Local\Temp\jl_FpGwGs\Project.toml`
  [336ed68f] CSV v0.10.14
  [a93c6f00] DataFrames v1.7.0
  [a5390f91] ZipFile v0.10.1

In the CSV docs just under the title Reading from a zip file, the example fails at the line a_copy = CSV.File(a_file_in_zip) |> DataFrame specifically at the CSV.File(a_file_in_zip) command.

Any hints?

Please share the error message with us :slight_smile: Just copy-paste it and post it as code block.

This was done with CSV 0.10.13 rather than 0.10.14, but the same error.

julia> z = ZipFile.Reader("a.zip")
ZipFile.Reader for IOStream(<file a.zip>) containing 1 files:

uncompressedsize method  mtime            name
----------------------------------------------
               8 Store   2024-10-11 14-23 a.csv


julia> a_file_in_zip = filter(x->x.name == "a.csv", z.files)[1]
ZipFile.ReadableFile(name=a.csv, method=Store, uncompresssedsize=8, compressedsize=8, mtime=1.728671032e9)

julia> a_copy = CSV.File(a_file_in_zip) |> DataFrame
ERROR: IOError: unlink("C:\\Users\\jakez\\AppData\\Local\\Temp\\jl_1E5A.tmp"): permission denied (EACCES)
Stacktrace:
 [1] uv_error
   @ .\libuv.jl:106 [inlined]
 [2] unlink(p::String)
   @ Base.Filesystem .\file.jl:1105
 [3] rm(path::String; force::Bool, recursive::Bool)
   @ Base.Filesystem .\file.jl:283
 [4] rm
   @ .\file.jl:273 [inlined]
 [5] CSV.File(ctx::CSV.Context, chunking::Bool)
   @ CSV C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:344
 [6] File
   @ C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:227 [inlined]
 [7] #File#32
   @ C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:223 [inlined]
 [8] CSV.File(source::ZipFile.ReadableFile)
   @ CSV C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:162
 [9] top-level scope
   @ REPL[16]:1

julia>

The example works with Julia 1.10.5. It was a good reason to finally install Juliaup and conveniently switch between versions of Julia.

Maybe it switched to a new temporary directory between versions, and for the new one C:\\Users\\jakez\\AppData\\Local\\Temp you don’t have permissions set up correctly?

I reported this as a bug several months ago:

and this thread:

I have not tried 1.11 yet, but I noted that CSV.File has the option buffer_in_memory=true, perhaps it will avoid the error since no temporary file is created. Could you try it?

Okay it seems that there might be two problems, one to do with file permissions and another one. Let’s start with the one where I work in a directory where I know I have write permissions. Taking it directly from the example referred to in post 1:

Blockquote
I have not tried 1.11 yet, but I noted that CSV.File has the option buffer_in_memory=true , perhaps it will avoid the error since no temporary file is created. Could you try it?

The following is with and without the `buffer_in_memory=true’ option.

julia> z = ZipFile.Reader("a2.zip") # or "a2.zip"
ZipFile.Reader for IOStream(<file a2.zip>) containing 1 files:

uncompressedsize method  mtime            name
----------------------------------------------
               8 Deflate 2024-10-14 07-48 a.csv


julia> a_file_in_zip = filter(x->x.name == "a.csv", z.files)[1]
ZipFile.ReadableFile(name=a.csv, method=Deflate, uncompresssedsize=8, compressedsize=10, mtime=1.728906532e9)

julia> a_copy = CSV.File(a_file_in_zip) |> DataFrame
ERROR: IOError: unlink("C:\\Users\\jakez\\AppData\\Local\\Temp\\jl_591A.tmp"): permission denied (EACCES)
Stacktrace:
 [1] uv_error
   @ .\libuv.jl:106 [inlined]
 [2] unlink(p::String)
   @ Base.Filesystem .\file.jl:1105
 [3] rm(path::String; force::Bool, recursive::Bool)
   @ Base.Filesystem .\file.jl:283
 [4] rm
   @ .\file.jl:273 [inlined]
 [5] CSV.File(ctx::CSV.Context, chunking::Bool)
   @ CSV C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:344
 [6] File
   @ C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:227 [inlined]
 [7] #File#32
   @ C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:223 [inlined]
 [8] CSV.File(source::ZipFile.ReadableFile)
   @ CSV C:\Users\jakez\.julia\packages\CSV\cwX2w\src\file.jl:162
 [9] top-level scope
   @ REPL[13]:1

julia>

julia> a_copy = CSV.File(a_file_in_zip, buffer_in_memory=true) |> DataFrame
0×0 DataFrame

No error when buffer_in_memory=true, but it has a 0x0 DataFrame, which is incorrect.

Now going back to a temporary environment on a Win 11 machine ]activate --temp where my write permissions are the Windows default and probably messed up, and the same example from post 1, when I try to write the zip file I also get an error as follows:

julia> z = ZipFile.Writer("a2.zip")
ERROR: SystemError: opening file "a2.zip": Permission denied
Stacktrace:
 [1] systemerror(p::String, errno::Int32; extrainfo::Nothing)
   @ Base .\error.jl:176
 [2] systemerror
   @ .\error.jl:175 [inlined]
 [3] open(fname::String; lock::Bool, read::Nothing, write::Nothing, create::Nothing, truncate::Bool, append::Nothing)
   @ Base .\iostream.jl:295
 [4] open
   @ .\iostream.jl:277 [inlined]
 [5] open(fname::String, mode::String; lock::Bool)
   @ Base .\iostream.jl:358
 [6] open
   @ .\iostream.jl:357 [inlined]
 [7] ZipFile.Writer(filename::String)
   @ ZipFile C:\Users\jakez\.julia\packages\ZipFile\yQ7yx\src\ZipFile.jl:179
 [8] top-level scope
   @ REPL[5]:1

From Windows 3.1 days and even before from DOS days, I have always put my local work in C:\data, and have found I don’t need to worry about what Windows uses for default file permissions.

You should not need to handle the file with ZipFile.Reader, if there is just one file inside. CSV.File("a2.zip", buffer_in_memory=true) would do the trick, with CSV.read("a2.zip", DataFrame; buffer_in_memory=true) directly creating a DataFrame.

In my use case there are many files in the zipped file. I am using the example from the manual as a MEW that works with 1.10.5 but not with 1.11.0 and reproduces the problem I am seeing with my code.

This PR should fix this issue Fix reading gzipped file in Julia 1.11 on Windows by nhz2 · Pull Request #1144 · JuliaData/CSV.jl · GitHub

2 Likes