package main ///* //#include //*/ //import "C" //import ( // "encoding/csv" // "encoding/json" // "fmt" // "io" // "os" // "path/filepath" // "strings" // "sync" // "sync/atomic" // "time" // "unsafe" //) // //// CSVManager CSV全局管理器 //type CSVManager struct { // files sync.Map // handle -> *CSVFile (并发安全的映射) // nextHandle int64 // 生成唯一句柄 // errorMsg string // 全局错误信息 // mu sync.RWMutex // 管理器级别的锁 //} // //// CSVFile 文件结构 //type CSVFile struct { // filename string // 实际文件路径 // handle int64 // 唯一句柄 // delimiter rune // 分隔符(如 ',') // hasHeader bool // 是否有标题行 // // // 内存数据缓存 // data [][]string // 内存中的数据行 // header []string // 标题行(如果有) // fileSize int64 // 文件大小 // modified bool // 标记是否被修改 // // // 并发控制 // mu sync.RWMutex // 文件级锁 // rowLocks []*sync.RWMutex // 行级锁 // rowMu sync.Mutex // 行锁数组保护 // readers int32 // 活跃读取器计数 // writers int32 // 活跃写入器计数 // saving int32 // 正在保存的goroutine计数 // saveErr chan error // 保存错误通道 // done chan struct{} // 关闭信号 //} // //// 单例模式的管理器 //var manager *CSVManager //var once sync.Once // //// newCSVFile 创建新的CSVFile对象 //func newCSVFile(filename string, delimiter rune, hasHeader bool) *CSVFile { // return &CSVFile{ // filename: filename, // delimiter: delimiter, // hasHeader: hasHeader, // data: make([][]string, 0), // rowLocks: make([]*sync.RWMutex, 0), // saveErr: make(chan error, 1), // done: make(chan struct{}), // } //} // //// getManager 获取全局管理器(单例) //func getManager() *CSVManager { // once.Do(func() { // manager = &CSVManager{ // nextHandle: 1, // } // }) // return manager //} // //// setError 设置错误信息 //func setError(err string) { // mgr := getManager() // mgr.mu.Lock() // mgr.errorMsg = err // mgr.mu.Unlock() //} // //// 初始化管理器 //func initCSVManager() int64 { // _ = getManager() // return 0 // 成功 //} // //// 打开/创建CSV文件(句柄) //func openCSVFile(filename string, delimiter rune, hasHeader bool) int64 { // // 创建CSV全局管理器 // mgr := getManager() // // // 先检查文件是否已经打开 // var existingHandle int64 = -1 // mgr.files.Range(func(key, value interface{}) bool { // file := value.(*CSVFile) // // 比较文件路径(使用绝对路径确保一致性) // absFilename, _ := filepath.Abs(filename) // absExisting, _ := filepath.Abs(file.filename) // // if absFilename == absExisting { // fmt.Println("absFilename", absFilename) // fmt.Println("absExisting", absExisting) // fmt.Println("bool", absFilename == absExisting) // // existingHandle = key.(int64) // return false // 停止遍历 // } // return true // 继续遍历 // }) // // // 如果文件已经打开,返回现有句柄 // if existingHandle != -1 { // fmt.Printf("文件已打开,返回现有句柄: %d\n", existingHandle) // return existingHandle // } // // // 生成句柄 // handle := atomic.AddInt64(&mgr.nextHandle, 1) // // // 创建文件对象 // file := newCSVFile(filename, delimiter, hasHeader) // file.handle = handle // // // 加载文件数据 // if err := file.load(); err != nil { // setError(err.Error()) // return -1 // } // // // 存储到管理器 // mgr.files.Store(handle, file) // return handle //} // //// 读取多行数据 //func readRows(handle int64, startRow, count int64, buffer []byte) int64 { // mgr := getManager() // // // 获取文件对象 // val, ok := mgr.files.Load(handle) // if !ok { // setError("Invalid file handle") // return -1 // } // // file := val.(*CSVFile) // atomic.AddInt32(&file.readers, 1) // defer atomic.AddInt32(&file.readers, -1) // // // 获取读取锁 // file.mu.RLock() // defer file.mu.RUnlock() // // totalRows := int64(len(file.data)) // if startRow < 0 || startRow >= totalRows { // return 0 // } // // // 计算实际读取行数 // endRow := startRow + count // if endRow > totalRows { // endRow = totalRows // } // // rowsToRead := endRow - startRow // // // 将数据复制到缓冲区 // bytesWritten := 0 // // for i := startRow; i < endRow; i++ { // row := file.data[i] // // // 获取行读锁 // if rowLock := file.getRowLock(int(i)); rowLock != nil { // rowLock.RLock() // } // // for _, cell := range row { // // 写入单元格长度 // cellLen := len(cell) // if bytesWritten+4 > len(buffer) { // break // } // // // 写入4字节长度 // buffer[bytesWritten] = byte(cellLen & 0xFF) // buffer[bytesWritten+1] = byte((cellLen >> 8) & 0xFF) // buffer[bytesWritten+2] = byte((cellLen >> 16) & 0xFF) // buffer[bytesWritten+3] = byte((cellLen >> 24) & 0xFF) // bytesWritten += 4 // // // 写入单元格数据 // if bytesWritten+cellLen > len(buffer) { // // 缓冲区不足,回退长度写入 // bytesWritten -= 4 // break // } // // copy(buffer[bytesWritten:bytesWritten+cellLen], cell) // bytesWritten += cellLen // } // // // 写入行结束标记 // if bytesWritten+4 <= len(buffer) { // // 4字节的0表示行结束 // buffer[bytesWritten] = 0 // buffer[bytesWritten+1] = 0 // buffer[bytesWritten+2] = 0 // buffer[bytesWritten+3] = 0 // bytesWritten += 4 // } // // // 释放行锁 // if rowLock := file.getRowLock(int(i)); rowLock != nil { // rowLock.RUnlock() // } // // if bytesWritten >= len(buffer) { // break // } // } // // return rowsToRead //} // //// 写入/覆盖行数据 //func writeRows(handle int64, rowData [][]string, header int) int64 { // mgr := getManager() // // // 获取文件对象 // val, ok := mgr.files.Load(handle) // if !ok { // setError("文件无效句柄!") // return -1 // } // // file := val.(*CSVFile) // // // 获取写入锁 // file.mu.Lock() // defer file.mu.Unlock() // // atomic.AddInt32(&file.writers, 1) // defer atomic.AddInt32(&file.writers, -1) // // // 清空现有数据(因为这是覆盖写入) // file.data = make([][]string, 0, len(rowData)) // if header == 0 { // file.header = rowData[0] // // 添加新数据 // file.data = rowData[1:] // } else { // // 添加新数据 // for _, row := range rowData { // file.data = append(file.data, row) // } // } // // // 扩展行锁数组 // file.rowMu.Lock() // file.rowLocks = make([]*sync.RWMutex, len(file.data)) // for i := range file.rowLocks { // file.rowLocks[i] = &sync.RWMutex{} // } // file.rowMu.Unlock() // // file.modified = true // // 异步保存到文件 // go file.saveAsync() // return int64(len(file.data)) //} // //// 加载CSV文件到内存 //func (f *CSVFile) load() error { // f.mu.Lock() // defer f.mu.Unlock() // // // 打开文件 // file, err := os.Open(f.filename) // if err != nil { // // 文件不存在则创建空文件 // if os.IsNotExist(err) { // f.data = make([][]string, 0) // 初始化空数据 // f.rowLocks = make([]*sync.RWMutex, 0) // 初始化空行锁数组 // return nil // } // return fmt.Errorf("文件不存在: %v", err) // } // // 确保函数结束时关闭文件 // defer file.Close() // // // 获取文件大小 // stat, _ := file.Stat() // 获取文件信息 // f.fileSize = stat.Size() // 获取文件大小 // // // 创建CSV读取器 // reader := csv.NewReader(file) // reader.Comma = f.delimiter // 设置分隔符(默认逗号) // reader.LazyQuotes = true // 允许宽松的引号解析 // reader.TrimLeadingSpace = true // 去除字段前的空格 // // // 关键修改:允许变长记录,不强制检查字段数量 // reader.FieldsPerRecord = -1 // firstRecord, err := reader.Read() // if err != nil { // if err == io.EOF { // // 空文件 // f.data = make([][]string, 0) // f.rowLocks = make([]*sync.RWMutex, 0) // return nil // } // return err // } // maxColumns := len(firstRecord) // allData := [][]string{firstRecord} // // // 读取剩余行 // for { // record, err := reader.Read() // if err == io.EOF { // break // } // if err != nil { // // 对于有问题的行,可以填充或跳过 // continue // } // // // 确保所有行都有相同的列数 // if len(record) < maxColumns { // // 填充缺失的列为空字符串 // paddedRecord := make([]string, maxColumns) // copy(paddedRecord, record) // for i := len(record); i < maxColumns; i++ { // paddedRecord[i] = "" // } // record = paddedRecord // } else if len(record) > maxColumns { // // 如果行有更多列,更新最大列数 // maxColumns = len(record) // // 重新处理之前的所有行 // for i := range allData { // if len(allData[i]) < maxColumns { // paddedRecord := make([]string, maxColumns) // copy(paddedRecord, allData[i]) // allData[i] = paddedRecord // } // } // } // // allData = append(allData, record) // } // // if len(allData) == 0 { // f.data = make([][]string, 0) // f.rowLocks = make([]*sync.RWMutex, 0) // return nil // } // // // 处理表头 // if f.hasHeader && len(allData) > 0 { // f.header = allData[0] // f.data = allData[1:] // } else { // f.data = allData // } // // // 初始化行锁 // f.initRowLocks() // // return nil //} // //// initRowLocks 初始化行锁数组 //func (f *CSVFile) initRowLocks() { // count := len(f.data) // f.rowLocks = make([]*sync.RWMutex, count) // for i := 0; i < count; i++ { // f.rowLocks[i] = &sync.RWMutex{} // } //} // //// getRowLock 获取行锁(线程安全) //func (f *CSVFile) getRowLock(rowIndex int) *sync.RWMutex { // if rowIndex < 0 { // return nil // } // // f.rowMu.Lock() // defer f.rowMu.Unlock() // // // 确保行锁存在 // if rowIndex >= len(f.rowLocks) { // // 扩展行锁数组 // newLocks := make([]*sync.RWMutex, rowIndex+1) // copy(newLocks, f.rowLocks) // for i := len(f.rowLocks); i <= rowIndex; i++ { // newLocks[i] = &sync.RWMutex{} // } // f.rowLocks = newLocks // } // // return f.rowLocks[rowIndex] //} // //// save 保存到文件 //func (f *CSVFile) save() error { // // 标记正在保存 // if !atomic.CompareAndSwapInt32(&f.saving, 0, 1) { // // 已经在保存中,直接返回 // return nil // } // defer atomic.StoreInt32(&f.saving, 0) // // // 如果没有修改,直接返回 // f.mu.RLock() // if !f.modified { // f.mu.RUnlock() // return nil // } // // 复制数据 // dataCopy := make([][]string, len(f.data)) // // for i := range f.data { // dataCopy[i] = make([]string, len(f.data[i])) // copy(dataCopy[i], f.data[i]) // } // // 复制表头 // headerCopy := make([]string, len(f.header)) // copy(headerCopy, f.header) // // 复制配置(值类型,直接赋值) // hasHeader := f.hasHeader // delimiter := f.delimiter // filename := f.filename // f.mu.RUnlock() // 释放读锁 // // // 创建临时文件(使用不同的扩展名避免冲突) // tempFile := filename + ".tmp" // file, err := os.Create(tempFile) // if err != nil { // return err // } // // // 创建CSV写入器 // writer := csv.NewWriter(file) // writer.Comma = delimiter // // // 写入数据 // if hasHeader && len(headerCopy) > 0 { // if err := writer.Write(headerCopy); err != nil { // file.Close() // os.Remove(tempFile) // return err // } // } // // if err := writer.WriteAll(dataCopy); err != nil { // file.Close() // os.Remove(tempFile) // return err // } // // writer.Flush() // if err := writer.Error(); err != nil { // file.Close() // os.Remove(tempFile) // return err // } // // // 关闭文件,确保数据写入磁盘 // if err := file.Close(); err != nil { // os.Remove(tempFile) // return err // } // // // 尝试重命名,如果失败可能是文件被占用 // var renameErr error // for retry := 0; retry < 3; retry++ { // renameErr = os.Rename(tempFile, filename) // if renameErr == nil { // break // } // time.Sleep(100 * time.Millisecond) // 等待重试 // } // // if renameErr != nil { // os.Remove(tempFile) // return renameErr // } // // // 标记为已保存 // f.mu.Lock() // f.modified = false // f.mu.Unlock() // // return nil //} // //// saveAsync 异步保存,带错误处理 //func (f *CSVFile) saveAsync() { // select { // case f.saveErr <- f.save(): // // 保存完成 // default: // // 通道已满,忽略错误 // } //} // //// 追加行数据 //func appendRows(handle int64, rowsData []byte, rowCount int64) int { // mgr := getManager() // // // 获取文件对象 // val, ok := mgr.files.Load(handle) // if !ok { // setError("Invalid file handle") // return -1 // } // // file := val.(*CSVFile) // // // 获取写入锁 // file.mu.Lock() // atomic.AddInt32(&file.writers, 1) // // // 解析行数据 // offset := 0 // // for i := int64(0); i < rowCount; i++ { // var row []string // // // 读取行数据 // for { // if offset+4 > len(rowsData) { // break // } // // cellLen := int(uint32(rowsData[offset]) | // uint32(rowsData[offset+1])<<8 | // uint32(rowsData[offset+2])<<16 | // uint32(rowsData[offset+3])<<24) // offset += 4 // // if cellLen == 0 { // break // } // // if offset+cellLen > len(rowsData) { // break // } // // cell := string(rowsData[offset : offset+cellLen]) // offset += cellLen // row = append(row, cell) // } // // // 追加到数据 // file.data = append(file.data, row) // } // // file.modified = true // // atomic.AddInt32(&file.writers, -1) // file.mu.Unlock() // // // 异步保存 // go file.saveAsync() // // // 获取总行数 // count := getRowCount(handle) // fmt.Println("count:", count) // return int(count) //} // //// 打开/创建CSV文件(句柄) //func createOpenCSVFile(filename string, delimiter rune, hasHeader bool) int64 { // // 创建CSV全局管理器 // mgr := getManager() // // // 生成句柄 // handle := atomic.AddInt64(&mgr.nextHandle, 1) // // // 创建文件对象 // file := newCSVFile(filename, delimiter, hasHeader) // file.handle = handle // // //// 加载文件数据 // //if err := file.load(); err != nil { // // setError(err.Error()) // // return -1 // //} // // // 存储到管理器 // mgr.files.Store(handle, file) // // return handle //} // //// updateCSVRowSafe 修改csv文件行数据 //func updateCSVRowSafe(handleID int64, rowNum int, newRow []string) error { // mgr := getManager() // // // 获取文件对象 // val, ok := mgr.files.Load(handleID) // if !ok { // setError("Invalid file handle") // return fmt.Errorf("无效句柄: %d", handleID) // } // file := val.(*CSVFile) // // // 1. 创建临时文件 // tempDir := filepath.Dir(file.filename) // if tempDir == "" { // tempDir = "." // } // // tempFile, err := os.CreateTemp(tempDir, "temp_*.csv") // if err != nil { // return fmt.Errorf("创建临时文件失败: %v", err) // } // tempFileName := tempFile.Name() // // // 确保临时文件被关闭和清理 // defer func() { // tempFile.Close() // // 如果临时文件还存在(替换失败),则清理它 // if _, err := os.Stat(tempFileName); err == nil { // os.Remove(tempFileName) // } // }() // // // 2. 读取原始文件 // sourceFile, err := os.Open(file.filename) // if err != nil { // return fmt.Errorf("打开源文件失败: %v", err) // } // defer sourceFile.Close() // // // 3. 读取并处理数据 // reader := csv.NewReader(sourceFile) // allRows, err := reader.ReadAll() // if err != nil { // return fmt.Errorf("读取CSV失败: %v", err) // } // // // 4. 验证并更新 // if rowNum < 1 || rowNum > len(allRows) { // return fmt.Errorf("行号 %d 超出范围 (1-%d)", rowNum, len(allRows)) // } // // // 显示修改前后的对比 // oldRow := allRows[rowNum-1] // fmt.Printf("修改前第 %d 行: %v\n", rowNum, oldRow) // fmt.Printf("修改后第 %d 行: %v\n", rowNum, newRow) // // allRows[rowNum-1] = newRow // // // 5. 写入临时文件 // writer := csv.NewWriter(tempFile) // if err := writer.WriteAll(allRows); err != nil { // return fmt.Errorf("写入临时文件失败: %v", err) // } // writer.Flush() // // if err := writer.Error(); err != nil { // return fmt.Errorf("刷新写入失败: %v", err) // } // // // 6. 确保数据写入磁盘 // if err := tempFile.Sync(); err != nil { // return fmt.Errorf("同步文件失败: %v", err) // } // tempFile.Close() // // // 7. 使用复制而不是重命名(解决Windows文件占用问题) // if err := copyFile(tempFileName, file.filename); err != nil { // return fmt.Errorf("复制文件失败: %v", err) // } // // fmt.Printf("✅ 成功更新第 %d 行,文件已直接更新\n", rowNum) // // return nil //} // //// copyFile 复制文件内容 //func copyFile(src, dst string) error { // // 打开源文件 // source, err := os.Open(src) // if err != nil { // return err // } // defer source.Close() // // // 创建目标文件 // destination, err := os.Create(dst) // if err != nil { // return err // } // defer destination.Close() // // // 复制内容 // _, err = io.Copy(destination, source) // if err != nil { // return err // } // // // 确保数据写入磁盘 // err = destination.Sync() // if err != nil { // return err // } // // return nil //} // //// 获取总行数 //func getRowCount(handle int64) int64 { // mgr := getManager() // // val, ok := mgr.files.Load(handle) // if !ok { // setError("Invalid file handle") // return -1 // } // // file := val.(*CSVFile) // file.mu.RLock() // defer file.mu.RUnlock() // if file.header != nil { // return int64(len(file.data) + 1) // } // return int64(len(file.data)) //} // //// 搜索行 //func findRows(handle int64, searchText string, columnIndex int64, resultBuffer []byte, maxResults int64) int64 { // mgr := getManager() // // val, ok := mgr.files.Load(handle) // if !ok { // setError("Invalid file handle") // return -1 // } // // file := val.(*CSVFile) // // file.mu.RLock() // defer file.mu.RUnlock() // // atomic.AddInt32(&file.readers, 1) // defer atomic.AddInt32(&file.readers, -1) // // var foundRows []int64 // // // 搜索行 // for i, row := range file.data { // if maxResults > 0 && int64(len(foundRows)) >= maxResults { // break // } // // // 获取行读锁 // if rowLock := file.getRowLock(i); rowLock != nil { // rowLock.RLock() // } // // // 检查列 // if columnIndex < 0 || columnIndex >= int64(len(row)) { // // 搜索所有列 // for _, cell := range row { // if cell == searchText { // foundRows = append(foundRows, int64(i)) // break // } // } // } else if row[columnIndex] == searchText { // foundRows = append(foundRows, int64(i)) // } // // // 释放行锁 // if rowLock := file.getRowLock(i); rowLock != nil { // rowLock.RUnlock() // } // } // // // 写入结果到缓冲区 // if resultBuffer != nil && len(foundRows) > 0 { // bytesWritten := 0 // // for _, rowIndex := range foundRows { // if bytesWritten+8 > len(resultBuffer) { // break // } // // // 写入行索引(8字节) // for j := 0; j < 8; j++ { // resultBuffer[bytesWritten] = byte((rowIndex >> (uint(j) * 8)) & 0xFF) // bytesWritten++ // } // } // } // // return int64(len(foundRows)) //} // //// 合并多个CSV文件(线程安全) //func mergeCSVFiles(handles []int64, outputFilename string, delimiter rune, hasHeader bool) int64 { // mgr := getManager() // // // 验证所有句柄并获取文件对象 // files := make([]*CSVFile, 0, len(handles)) // for _, handle := range handles { // val, ok := mgr.files.Load(handle) // if !ok { // setError("Invalid file handle: " + string(handle)) // return -1 // } // files = append(files, val.(*CSVFile)) // } // // // 创建输出文件对象 // outputFile := newCSVFile(outputFilename, delimiter, hasHeader) // outputFile.modified = true // 标记为需要保存 // // // 第一步:合并表头 // mergedHeader := make([]string, 0) // headerSet := make(map[string]bool) // // if hasHeader { // // 收集所有不重复的表头 // for _, file := range files { // file.mu.RLock() // if file.hasHeader && len(file.header) > 0 { // for _, h := range file.header { // if !headerSet[h] { // headerSet[h] = true // mergedHeader = append(mergedHeader, h) // } // } // } // file.mu.RUnlock() // } // // // 如果没有找到表头,创建一个默认的表头 // if len(mergedHeader) == 0 && len(files) > 0 { // files[0].mu.RLock() // maxColumns := len(files[0].data[0]) // files[0].mu.RUnlock() // // for i := 0; i < maxColumns; i++ { // mergedHeader = append(mergedHeader, fmt.Sprintf("Column%d", i+1)) // } // } // } // outputFile.header = mergedHeader // // // 第二步:合并数据 // mergedData := make([][]string, 0) // // // 为每个输入文件创建读取锁并并发读取 // var wg sync.WaitGroup // dataChan := make(chan [][]string, len(files)) // errorChan := make(chan error, len(files)) // // for idx, file := range files { // wg.Add(1) // go func(fileIdx int, f *CSVFile) { // defer wg.Done() // // // 获取文件的读取锁 // f.mu.RLock() // defer f.mu.RUnlock() // // // 增加活跃读取器计数 // atomic.AddInt32(&f.readers, 1) // defer atomic.AddInt32(&f.readers, -1) // // // 读取数据 // fileData := make([][]string, len(f.data)) // for i := 0; i < len(f.data); i++ { // // 获取行读锁 // if rowLock := f.getRowLock(i); rowLock != nil { // rowLock.RLock() // } // // // 复制行数据 // row := make([]string, len(f.data[i])) // copy(row, f.data[i]) // // // 释放行锁 // if rowLock := f.getRowLock(i); rowLock != nil { // rowLock.RUnlock() // } // // fileData[i] = row // } // // // 如果需要处理表头映射 // if hasHeader && f.hasHeader && len(f.header) > 0 { // // 创建列映射:源列 -> 目标列 // columnMapping := make(map[int]int) // for srcIdx, srcHeader := range f.header { // for dstIdx, dstHeader := range mergedHeader { // if srcHeader == dstHeader { // columnMapping[srcIdx] = dstIdx // break // } // } // } // // // 重新排列数据以匹配合并后的表头 // for i := 0; i < len(fileData); i++ { // newRow := make([]string, len(mergedHeader)) // for srcIdx, dstIdx := range columnMapping { // if srcIdx < len(fileData[i]) { // newRow[dstIdx] = fileData[i][srcIdx] // } // } // fileData[i] = newRow // } // } else if hasHeader && len(mergedHeader) > 0 { // // 文件没有表头,但输出需要表头 // // 简单地将数据填充到对应位置 // for i := 0; i < len(fileData); i++ { // newRow := make([]string, len(mergedHeader)) // for j := 0; j < len(fileData[i]) && j < len(newRow); j++ { // newRow[j] = fileData[i][j] // } // fileData[i] = newRow // } // } // // // 将处理后的数据发送到通道 // dataChan <- fileData // }(idx, file) // } // // // 等待所有goroutine完成 // go func() { // wg.Wait() // close(dataChan) // close(errorChan) // }() // // // 收集所有数据 // for data := range dataChan { // mergedData = append(mergedData, data...) // } // // // 检查是否有错误 // select { // case err := <-errorChan: // if err != nil { // setError("Error merging files: " + err.Error()) // return -1 // } // default: // } // // // 第三步:设置输出文件的数据 // outputFile.data = mergedData // outputFile.initRowLocks() // // // 第四步:保存到文件 // if err := outputFile.save(); err != nil { // setError("Error saving merged file: " + err.Error()) // return -1 // } // // // 第五步:将输出文件添加到管理器 // handle := atomic.AddInt64(&mgr.nextHandle, 1) // outputFile.handle = handle // mgr.files.Store(handle, outputFile) // // return handle //} // //// 关闭文件 //func closeCSVFile(handle int64) int64 { // mgr := getManager() // // val, ok := mgr.files.Load(handle) // if !ok { // setError("文件句柄无效!") // return -1 // } // // file := val.(*CSVFile) // // // 等待所有读写操作完成 // for atomic.LoadInt32(&file.readers) > 0 || atomic.LoadInt32(&file.writers) > 0 { // time.Sleep(time.Millisecond) // } // // // 等待异步保存完成 // for i := 0; i < 100; i++ { // 最多等待100ms // if atomic.LoadInt32(&file.saving) == 0 { // break // } // time.Sleep(time.Millisecond) // } // // // 如果有正在进行的保存,等待一小段时间 // if atomic.LoadInt32(&file.saving) > 0 { // time.Sleep(50 * time.Millisecond) // } // // // 检查是否需要保存 // file.mu.RLock() // needSave := file.modified // file.mu.RUnlock() // // if needSave { // // 同步保存修改 // if err := file.save(); err != nil { // setError(err.Error()) // return -1 // } // } // // // 从管理器移除 // mgr.files.Delete(handle) // // //// 安全关闭通道(如果存在) // //if file.done != nil { // // close(file.done) // //} // // return 0 //} // //// 获取错误信息 //func getError() string { // mgr := getManager() // mgr.mu.RLock() // defer mgr.mu.RUnlock() // // if mgr.errorMsg == "" { // return "" // } // // err := mgr.errorMsg // mgr.errorMsg = "" // 清空错误 // // return err //} // //func parseSimpleTable(goData string) [][]string { // lines := strings.Split(strings.TrimSpace(goData), "\n") // result := make([][]string, len(lines)) // // for i, line := range lines { // // 根据你的分隔符分割,这里用逗号举例 // fields := strings.Split(line, ",") // // 如果需要去除每个字段的空格 // for j := range fields { // fields[j] = strings.TrimSpace(fields[j]) // } // result[i] = fields // } // // return result //} // //// ============ C 导出接口 ============ // ////export InitCSVManager //func InitCSVManager() C.longlong { // return C.longlong(initCSVManager()) //} // //// OpenCSVFile 打开/创建CSV文件 //// ////export OpenCSVFile //func OpenCSVFile(filename *C.char, delimiter C.char, hasHeader C.int) C.longlong { // return C.longlong(openCSVFile(C.GoString(filename), rune(delimiter), hasHeader != 0)) //} // //// CSV响应结构体 //type CSVResponse struct { // Success bool `json:"success"` // Message string `json:"message,omitempty"` // Data interface{} `json:"data,omitempty"` //} // //// UpdateCSVRowSafe 修改csv文件行数据 //// ////export UpdateCSVRowSafe //func UpdateCSVRowSafe(handleID C.longlong, rowNum C.int, newRow *C.char) *C.char { // goHandle := int64(handleID) // goRowNum := int(rowNum) // goNewRow := C.GoString(newRow) // var row []string // var csvResponse CSVResponse // // 解析JSON // err := json.Unmarshal([]byte(goNewRow), &row) // if err != nil { // csvResponse = CSVResponse{ // Success: false, // Message: fmt.Sprintf("解析JSON失败: %v", err), // } // errorJson, _ := json.Marshal(csvResponse) // return C.CString(string(errorJson)) // } // // 修改csv行数据 // err = updateCSVRowSafe(goHandle, goRowNum, row) // if err != nil { // csvResponse = CSVResponse{ // Success: false, // Message: fmt.Sprintf(err.Error()), // } // errorJson, _ := json.Marshal(csvResponse) // return C.CString(string(errorJson)) // } else { // csvResponse = CSVResponse{ // Success: true, // } // } // // 转换为JSON字符串 // jsonData, err := json.Marshal(csvResponse) // if err != nil { // // 如果JSON序列化失败,返回错误信息 // csvResponse = CSVResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", err), // } // errorJson, _ := json.Marshal(csvResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // ////export CreateOpenCSVFile //func CreateOpenCSVFile(filename *C.char, delimiter C.char, hasHeader C.int) *C.char { // goFilename := C.GoString(filename) // goDelimiter := rune(delimiter) // var goHasHeader bool // if int(hasHeader) == 0 { // goHasHeader = true // } // goHasHeader = false // handle := createOpenCSVFile(goFilename, goDelimiter, goHasHeader) // var csvResponse CSVResponse // response := struct { // HandleID int64 `json:"handleID"` // }{ // HandleID: handle, // } // csvResponse.Success = true // csvResponse.Data = response // jsonData, _ := json.Marshal(csvResponse) // return C.CString(string(jsonData)) //} // //// ReadRows 读取多行数据 //// ////export ReadRows //func ReadRows(handle C.longlong, startRow C.longlong, count C.longlong, buffer *C.char, bufferSize C.int) C.longlong { // // 将 C 缓冲区转换为 Go 的字节切片 // goBuffer := unsafe.Slice((*byte)(unsafe.Pointer(buffer)), int(bufferSize)) // result := readRows(int64(handle), int64(startRow), int64(count), goBuffer) // return C.longlong(result) //} // //// WriteRows 写入/覆盖行数据 //// ////export WriteRows //func WriteRows(handle C.longlong, rowsData *C.char, header C.int) C.int { // goData := C.GoString(rowsData) // goHeader := int(header) // //data := parseSimpleTable(goData) // var data [][]string // err := json.Unmarshal([]byte(goData), &data) // if err != nil { // setError(err.Error()) // } // result := writeRows(int64(handle), data, goHeader) // return C.int(result) //} // //// AppendRows 追加行数据 //// ////export AppendRows //func AppendRows(handle C.longlong, rowsData *C.char, dataSize C.int, rowCount C.longlong) C.int { // goData := unsafe.Slice((*byte)(unsafe.Pointer(rowsData)), int(dataSize)) // result := appendRows(int64(handle), goData, int64(rowCount)) // return C.int(result) //} // //// GetRowCount 获取总行数 //// ////export GetRowCount //func GetRowCount(handle C.longlong) C.longlong { // result := getRowCount(int64(handle)) // return C.longlong(result) //} // //// FindRows 搜索行 //// ////export FindRows //func FindRows(handle C.longlong, searchText *C.char, columnIndex C.longlong, resultBuffer *C.char, bufferSize C.int, maxResults C.longlong) C.longlong { // goSearchText := C.GoString(searchText) // goResultBuffer := unsafe.Slice((*byte)(unsafe.Pointer(resultBuffer)), int(bufferSize)) // result := findRows(int64(handle), goSearchText, int64(columnIndex), goResultBuffer, int64(maxResults)) // return C.longlong(result) //} // //// MergeCSVFiles 合并多个CSV文件(线程安全) //// ////export MergeCSVFiles //func MergeCSVFiles(handlesPtr *C.longlong, handlesCount C.int, outputFilename *C.char, delimiter C.char, hasHeader C.int) C.longlong { // // 将C数组转换为Go切片 // goHandles := unsafe.Slice(handlesPtr, int(handlesCount)) // handles := make([]int64, len(goHandles)) // for i := 0; i < len(goHandles); i++ { // handles[i] = int64(goHandles[i]) // } // // 调用合并函数 // result := mergeCSVFiles(handles, C.GoString(outputFilename), rune(delimiter), hasHeader != 0) // return C.longlong(result) //} // //// CloseCSVFile 关闭文件 //// ////export CloseCSVFile //func CloseCSVFile(handle C.longlong) C.int { // result := closeCSVFile(int64(handle)) // return C.int(result) //} // //// GetError 获取错误信息 //// ////export GetError //func GetError(buffer *C.char, bufferSize C.int) C.int { // errMsg := getError() // if errMsg == "" { // return 0 // } // // // 将错误信息复制到缓冲区 // goBuffer := unsafe.Slice((*byte)(unsafe.Pointer(buffer)), int(bufferSize)) // n := copy(goBuffer, errMsg) // return C.int(n) //} // //// 导出函数:释放C字符串内存 //// ////export FreeCString //func FreeCString(str *C.char) { // C.free(unsafe.Pointer(str)) //} // //// CSV_VERSION 版本号 //const ( // CSV_VERSION = "v1" //) // //// 获取版本信息 //// ////export GetVersion //func GetVersion() *C.char { // return C.CString(CSV_VERSION) //} // //// main 函数是必需的,即使为空 //func main() { //}