You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

data.table::fwrite生成的gzip文件异常:Ubuntu管理器无法解压

使用data.table::fwrite生成的gzip文件无法被Ubuntu文件管理器正常解压的问题

问题现象

用data.table::fwrite(dt, 'teste.csv.gz')将data.table保存为gzip压缩文件后:

  • Ubuntu文件管理器解压时提示“空归档错误”,无法正常处理
  • 命令行执行gunzip -l teste.csv.gz返回异常的负压缩率(示例中为-1129.1%)
  • 但命令行gunzip teste.csv.gz可以正常解压文件
  • 若先导出未压缩CSV,再用系统gzip命令压缩,生成的文件既可以被Ubuntu文件管理器正常解压,gunzip -l也会显示正常的压缩率(示例中为55.8%)

重现代码

library(data.table)

# 创建测试数据
dt <- data.table(a = 1:100000,
                 b = runif(100000))

# 用fwrite直接生成gzip文件
fwrite(dt, 'teste.csv.gz')
# 查看压缩信息,显示异常比率
res <- system('gunzip -l teste.csv.gz', intern = TRUE)
res
#> [1] "         compressed        uncompressed  ratio uncompressed_name"
#> [2] "            1055898               85906 -1129.1% teste.csv"

# 命令行可正常解压
system('gunzip teste.csv.gz')

# 用系统gzip命令压缩,生成正常文件
system('gzip teste.csv')
res <- system('gunzip -l teste.csv.gz', intern = TRUE)
res
#> [1] "         compressed        uncompressed  ratio uncompressed_name"
#> [2] "            1054997             2388946  55.8% teste.csv"

sessionInfo()
#> R version 4.4.0 (2024-04-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 20.04.6 LTS
#> 
#> Matrix products: default
#> BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3;  LAPACK version 3.9.0
#> 
#> locale:
#>  [1] LC_CTYPE=pt_BR.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C              
#>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: America/Sao_Paulo
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] data.table_1.15.4
#> 
#> loaded via a namespace (and not attached):
#>  [1] styler_1.10.3     digest_0.6.35     fastmap_1.2.0     xfun_0.44        
#>  [5] magrittr_2.0.3    glue_1.7.0        R.utils_2.12.3    knitr_1.47       
#>  [9] htmltools_0.5.8.1 rmarkdown_2.27    lifecycle_1.0.4   cli_3.6.2        
#> [13] R.methodsS3_1.8.2 vctrs_0.6.5       reprex_2.1.0      withr_3.0.0      
#> [17] compiler_4.4.0    R.oo_1.26.0       R.cache_0.16.0    purrr_1.0.2      
#> [21] rstudioapi_0.16.0 tools_4.4.0       evaluate_0.23     yaml_2.3.8       
#> [25] rlang_1.1.3       fs_1.6.4

原因分析

这不是data.table::fwrite的bug,而是其gzip压缩实现与系统gzip的差异:

  • fwrite直接将数据压缩为gzip流写入文件,但未在gzip头部写入原始未压缩文件大小的元数据
  • Ubuntu文件管理器和gunzip -l依赖这个元数据来识别归档内容、计算压缩率,因此出现错误提示和异常比率
  • gunzip命令本身不依赖该元数据,可直接解压缩流,所以能正常解压

解决办法

方法1:先导出未压缩CSV,再用系统gzip压缩

fwrite(dt, 'teste.csv')
system('gzip teste.csv')

生成的文件完全兼容系统工具和文件管理器。

方法2:使用fwrite的compress参数(需data.table新版本)

升级到最新版data.table后,显式指定compress = "gzip"参数,生成的文件会包含完整的gzip元数据:

fwrite(dt, 'teste.csv.gz', compress = "gzip")

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:30:58