在Golang中,可以使用以下步骤将大文件分割为小文件,并重新组合合并
- 将大文件分割为多个临时文件(每个文件大小为1GB)
- 然后并发地从每个临时文件中提取ID,并将提取到的ID发送到一个通道中。
- 下来,通过等待所有提取ID的goroutine完成并关闭通道,将所有提取到的ID收集到一个切片中
- 最后,对切片进行倒序遍历,并将唯一的ID添加到一个新的切片中
func main() {
FilePath := "path/to/your/file.txt" // 替换为实际文件路径
// 分割文件
chunks, err := splitFile(filePath)
if err != nil {
fmt.Printf("无法分割文件:%s\n", err)
return
}
// 提取ID
ids := extractIDs(chunks)
// 合并并去重ID
uniqueIDs := mergeAndDeduplicate(ids)
// 输出结果
for _, id := range uniqueIDs {
fmt.Println(id)
}
}
// 分割文件为多个临时文件
// 分割文件为多个临时文件
func splitFile(filePath string) ([]string, error) {
const chunkSize = 1 * 1024 * 1024 * 1024 // 每个临时文件的大小(1GB)
file, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("无法打开文件:%s", err)
}
defer file.Close()
chunks := make([]string, 0)
buffer := make([]byte, chunkSize)
for i := 0; ; i {
n, err := file.Read(buffer)
if err != nil && err != io.EOF {
return nil, fmt.Errorf("读取文件时出错:%s", err)
}
if n == 0 {
break
}
chunkFilePath := fmt.Sprintf("temp_%d.txt", i) // 临时文件路径
chunkFile, err := os.Create(chunkFilePath)
if err != nil {
return nil, fmt.Errorf("无法创建临时文件:%s", err)
}
defer chunkFile.Close()
_, err = chunkFile.Write(buffer[:n])
if err != nil {
return nil, fmt.Errorf("写入临时文件时出错:%s", err)
}
chunks = append(chunks, chunkFilePath)
}
return chunks, nil
}
// 提取ID
func extractIDs(chunks []string) []int {
var wg sync.WaitGroup
wg.Add(len(chunks))
idsChan := make(chan int)
for _, chunkFilePath := range chunks {
go func(filePath string) {
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("无法打开文件:%s\n", err)
wg.Done()
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
id, err := strconv.Atoi(line)
if err != nil {
fmt.Printf("无效的ID:%s\n", line)
continue
}
idsChan <- id
}
wg.Done()
}(chunkFilePath)
}
go func() {
wg.Wait()
close(idsChan)
}()
ids := make([]int, 0)
for id := range idsChan {
ids = append(ids, id)
}
return ids
}
// 合并并去重ID
func mergeAndDeduplicate(ids []int) []int {
sort.Ints(ids)
uniqueIDs := make([]int, 0)
// 倒序遍历切片,将唯一的ID添加到uniqueIDs中
seen := make(map[int]bool)
for i := len(ids) - 1; i >= 0; i-- {
id := ids[i]
if !seen[id] {
uniqueIDs = append(uniqueIDs, id)
seen[id] = true
}
}
return uniqueIDs
}