使用xlsxio读写同一Excel文件时遭遇权限拒绝错误的技术问询
解决xlsxioread读取后xlsxiowrite写入同文件的权限问题
问题现象
执行代码后出现如下错误:
$ ./a Sheetname: Sheet1 Read value: dasf zip_close failed (2,13) can't close zip archive : Renaming temporary file failed: Permission denied
即使调用xlsxioread_close释放读取句柄,系统层面可能仍存在文件资源未完全释放的情况,导致xlsxiowrite在尝试覆盖原文件时,无法完成临时文件到原文件的重命名操作。
解决方案
最稳妥的处理方式是避免直接覆盖正在操作的原文件,采用「临时文件写入+替换原文件」的流程:
- 先将新内容写入临时文件
- 确认写入完成且无错误后,用临时文件替换原文件
这种方式彻底规避了原文件被占用的问题,同时也能在写入失败时避免破坏原文件。
修改后的代码
#include <xlsxio_write.h> #include <xlsxio_read.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> // 用于rename函数 int main() { xlsxiowriter writeHandle; xlsxioreader readHandle; xlsxioreadersheetlist sheetlist; xlsxioreadersheet sheet; const char* sheetname; char *value; //--------------------------------------------------- Read if ((readHandle = xlsxioread_open("test.xlsx")) == NULL) { fprintf(stderr, "Error open .xlsx file\n"); return 1; } if ((sheetlist = xlsxioread_sheetlist_open(readHandle)) != NULL) { sheetname = xlsxioread_sheetlist_next(sheetlist); printf("Sheetname: %s\n", sheetname); } if ((sheet = xlsxioread_sheet_open(readHandle, sheetname, XLSXIOREAD_SKIP_EMPTY_ROWS)) == NULL) { fprintf(stderr, "Error open sheet\n"); return 1; } xlsxioread_sheet_next_row(sheet); if ((value = xlsxioread_sheet_next_cell(sheet)) == NULL) { printf("Read null\n"); } else { printf("Read value: %s\n", value); xlsxioread_free(value); } xlsxioread_sheet_close(sheet); xlsxioread_close(readHandle); //--------------------------------------------------- Write to temporary file first const char* temp_file = "test_temp.xlsx"; if ((writeHandle = xlsxiowrite_open(temp_file, "1")) == NULL) { fprintf(stderr, "Error creating temporary .xlsx file\n"); return 1; } xlsxiowrite_add_cell_string(writeHandle, "test1"); xlsxiowrite_next_row(writeHandle); xlsxiowrite_add_cell_string(writeHandle, "test2"); xlsxiowrite_add_cell_string(writeHandle, "test3"); // 检查写入关闭是否成功 if (xlsxiowrite_close(writeHandle) != 0) { fprintf(stderr, "Error closing temporary file\n"); remove(temp_file); // 清理临时文件 return 1; } // 替换原文件 if (rename(temp_file, "test.xlsx") != 0) { fprintf(stderr, "Failed to replace original file: Permission denied\n"); remove(temp_file); // 清理临时文件 return 1; } return 0; }
关键修改点
- 写入目标改为临时文件
test_temp.xlsx,与原文件完全隔离 - 增加写入关闭后的错误检查,确保临时文件写入完整
- 使用
rename原子替换原文件,保证操作的安全性 - 任何步骤失败时都会清理临时文件,避免残留垃圾文件
内容的提问来源于stack exchange,提问作者Yonett
相关产品推荐
相关产品推荐

