Maison >développement back-end >Golang >Comment copier efficacement des fichiers clairsemés dans Go sans gonflement ?

Comment copier efficacement des fichiers clairsemés dans Go sans gonflement ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-03 17:06:02704parcourir

How Do You Efficiently Copy Sparse Files in Go Without Bloating?

Fichiers clairsemés gonflés avec io.Copy()

Lors de la copie de fichiers avec io.Copy(), les gros fichiers clairsemés ont tendance à gonfler de manière disproportionnée à leur destination. Ce comportement provient de la gestion des octets bruts par io.Copy(), qui n'a pas les moyens de transmettre des informations sur les trous de fichiers.

Gestion des trous

Pour gérer les trous , vous devez approfondir le package syscall et bricoler les valeurs SEEK_HOLE et SEEK_DATA pour lseek(2). Malheureusement, ces valeurs ne sont pas présentes dans le package syscall standard ou son homologue golang.org/x/sys.

Solution

Pour surmonter ce problème, suivez ces étapes :

  1. Mappez syscall.Seek() à lseek(2) sur les plateformes prises en charge.
  2. Déterminez les valeurs correctes pour SEEK_HOLE et SEEK_DATA pour vos plateformes cibles, car elles peuvent varier.

Par exemple, sous Linux, vous pouvez utiliser :

// +build linux

const (
    SEEK_DATA = 3
    SEEK_HOLE = 4
)

Lecture et transfert de fichiers fragmentés

Détecter les régions de données et lire à partir de eux lors de la lecture de fichiers clairsemés. Pour transférer des fichiers avec une parcimonie intacte, le processus est plus complexe et nécessite des considérations spécifiques à la plate-forme.

Approche spécifique à Linux

Sous Linux, utilisez fallocate(2) avec FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE pour percer un trou à la fin du fichier. En cas d'échec, mettez à zéro les blocs pour couvrir le trou.

Notes supplémentaires

  • Certains systèmes de fichiers, tels que FAT, ne prennent pas en charge les trous.
  • Vérifiez si la source et la destination se trouvent sur le même système de fichiers pour envisager d'utiliser syscall.Rename() pour un déplacement plus rapide des fichiers sans copier de données.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn