文件生成、拷贝减少内存、CPU使用率办法

核心技术解析
1.​零拷贝分片传输​
​内存映射 (mmap)​​:将源文件直接映射到虚拟内存,分片操作 mapped[offset:end]仅生成内存视图,​无数据复制。
​直接写入​:通过 destFile.Write()将分片数据直接写入目标文件,避免用户态缓冲区的额外拷贝
2.​资源安全管理​
​defer链式释放​:确保文件描述符和内存映射资源在任何情况下(包括错误)都会被释放
​同步刷盘​:destFile.Sync()强制内核缓存刷入磁盘,防止系统崩溃导致数据丢失(牺牲部分性能换取可靠性)
3.​大文件友好设计​
​流式分片处理​:按固定大小(4MB)逐片写入,支持 ​TB 级文件​ 而不会内存溢出
​物理内存按需加载​:操作系统通过缺页中断动态加载文件分片,减少瞬时内存压力

package main

import (
	"fmt"
	"github.com/edsrzf/mmap-go"
	"log"
	"os"
)

const chunkSize = 4 * 1024 * 1024 // 4MB分片

func main() {
	if len(os.Args) < 2 {
		log.Fatal("Usage: ./zero-copy-save <filename>")
	}
	filename := os.Args[1]
	destFile := fmt.Sprintf("/tmp/%v", filename)
	if err := saveFile(filename, destFile); err != nil {
		log.Fatalf("Error: %v", err)
	}
}

// 零拷贝分片保存到目标文件
func saveFile(inputFile, outputFile string) error {
	// 1. 打开源文件(只读)
	srcFile, err := os.Open(inputFile)
	if err != nil {
		return fmt.Errorf("open source file failed: %w", err)
	}
	defer srcFile.Close()

	// 2. 内存映射源文件(零拷贝)
	mapped, err := mmap.Map(srcFile, mmap.RDONLY, 0)
	if err != nil {
		return fmt.Errorf("mmap failed: %w", err)
	}
	defer mapped.Unmap()

	// 3. 创建目标文件(覆盖写入)
	destFile, err := os.Create(outputFile)
	if err != nil {
		return fmt.Errorf("create output file failed: %w", err)
	}
	defer destFile.Close()

	// 4. 分片写入目标文件
	for offset := 0; offset < len(mapped); {
		end := offset + chunkSize
		if end > len(mapped) {
			end = len(mapped)
		}
		chunk := mapped[offset:end] // 直接引用内存分片

		// 5. 零拷贝写入目标文件
		if _, err := destFile.Write(chunk); err != nil {
			return fmt.Errorf("write chunk failed: %w", err)
		}

		// 6. 可选:同步数据到磁盘(确保持久化)
		if err := destFile.Sync(); err != nil {
			log.Printf("Warning: sync failed (%v)", err)
		}

		log.Printf("Wrote chunk [offset=%d, size=%d]", offset, len(chunk))
		offset = end
	}

	log.Printf("Saved %d bytes → %s", len(mapped), outputFile)
	return nil
}

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*

English