使用流式函数解决v语言zstd程序解压缩失败问题

上文的简易压缩/解压程序在解压缩较大文件时出错,输出到文件为0字节。

bash 复制代码
请输入要解压的.zst文件路径: vzstd.zst
请输入解压后文件保存路径: var.txt
正在解压 vzstd.zst...
解压完成!
压缩文件: vzstd.zst (88089043 字节)
解压文件: var.txt (0 字节)        <---------------no data in output file
耗时: 0.43 秒

我在github上提出此问题

kbkpbot 回答如下

os.write_bytes(output_file, decompressed_data)
For small zstd file, you can use compress()/decompress() directly.

For large zstd file, because V internal array size limit(it use int which has a limit), you can't use a supper large buffer now, I suggest use a stream mode compress/decompress.

并提供了解决此问题的具体改用流式函数实现,

c 复制代码
const buf_in_size = 1024 * 1024
const buf_out_size = 1024 * 1024

fn decompress_file_fun(fname string, oname string, params zstd.DecompressParams) ! {
	mut fin := os.open_file(fname, 'rb')!
	mut fout := os.open_file(oname, 'wb')!
	defer {
		fin.close()
		fout.close()
	}

	mut buf_in := []u8{len: buf_in_size}
	mut buf_out := []u8{len: buf_out_size}

	mut dctx := zstd.new_dctx(params)!
	defer {
		dctx.free_dctx()
	}

	mut input := &zstd.InBuffer{
		src:  buf_in.data
		size: 0
		pos:  0
	}
	mut output := &zstd.OutBuffer{
		dst:  buf_out.data
		size: 0
		pos:  0
	}

	mut last_ret := usize(0)
	for {
		read_len := fin.read(mut buf_in)!
		input.src = buf_in.data
		input.size = usize(read_len)
		input.pos = 0
		for input.pos < input.size {
			output.dst = buf_out.data
			output.size = buf_out_size
			output.pos = 0
			ret := dctx.decompress_stream(output, input)!
			fout.write(buf_out[..output.pos])!
			last_ret = ret
		}
		if read_len < buf_in.len {
			break
		}
	}
	if last_ret != 0 {
		/* The last return value from DecompressStream did not end on a
         * frame, but we reached the end of the file! We assume this is an
         * error, and the input was truncated.
         */
		return error('EOF before end of stream: ${last_ret}')
	}
}

将此函数添加到源代码,并在decompress_file函数中用如下语句调用代替原有解压缩部分代码。

c 复制代码
    println("正在解压 ${input_file}...")
    start_time := time.now()

    decompress_file_fun(input_file, output_file)or {} //or {}必须,否则编译出错

    duration := time.since(start_time).seconds()

这样就可以解压缩完成了

c 复制代码
v -prod vzstd2.v

./vzstd2
ZSTD 压缩/解压工具
1. 压缩文件
2. 解压文件
3. 退出程序
请选择操作 (1-3): 2
请输入要解压的.zst文件路径: vzstd2.zst
请输入解压后文件保存路径: ccc.txt
正在解压 vzstd2.zst...
解压完成!
压缩文件: vzstd2.zst (88089043 字节)
解压文件: ccc.txt (106046919 字节)
耗时: 0.78 秒
相关推荐
AI3D_WebEngineer10 分钟前
企业级业务平台项目设计、架构、业务全解之组件库篇
前端·javascript·vue
charlie11451419136 分钟前
从零开始理解 CSS:让网页“活”起来的语言2
前端·css·笔记·学习·选择器·样式表·原生
浪裡遊1 小时前
Next.js路由系统
开发语言·前端·javascript·react.js·node.js·js
mapbar_front1 小时前
职场中的顶级能力—服务意识
前端
尽兴-1 小时前
[特殊字符] 微前端部署实战:Nginx 配置 HTTPS 与 CORS 跨域解决方案(示例版)
前端·nginx·https·跨域·cors·chrom
JIngJaneIL2 小时前
助农惠农服务平台|助农服务系统|基于SprinBoot+vue的助农服务系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·助农惠农服务平台
云外天ノ☼2 小时前
待办事项全栈实现:Vue3 + Node.js (Koa) + MySQL深度整合,构建生产级任务管理系统的技术实践
前端·数据库·vue.js·mysql·vue3·koa·jwt认证
一位搞嵌入式的 genius2 小时前
前端实战开发(三):Vue+Pinia中三大核心问题解决方案!!!
前端·javascript·vue.js·前端实战
塞纳河畔的歌2 小时前
保姆级教程 | 麒麟系统安装Edge浏览器
前端·edge
多睡觉觉2 小时前
数据字典:从"猜谜游戏"到"优雅编程"的奇幻之旅
前端