dongxie1907 2016-04-29 17:01
浏览 42
已采纳

Golang-为什么字符串切片元素不包含在exec cat中,除非我对其排序

I have a slightly funky issue in golang. Essentially I have a slice of strings which represent file paths. I then run a cat against those filepaths to combine the files before sorting, deduping, etc.

here is the section of code (where 'applicableReductions' is the string slice):

    applicableReductions := []string{}

    for _, fqFromListName := range fqFromListNames {
         filePath := GetFilePath()
         //BROKE CODE GOES HERE
    }
    applicableReductions = append(applicableReductions, filePath)

    fileOut, err := os.Create(toListWriteTmpFilePath)
    if err != nil {
        return err
    }
    cat := exec.Command("cat", applicableReductions...)
    catStdOut, err := cat.StdoutPipe()
    if err != nil {
        return err
    }
    go func(cat *exec.Cmd) error {
        if err := cat.Start(); err != nil {
            return fmt.Errorf("File reduction error (cat) : %s", err)
        }
        return nil
    }(cat)

    // Init Writer & write file
    writer := bufio.NewWriter(fileOut)
    defer writer.Flush()

    _, err = io.Copy(writer, catStdOut)
    if err != nil {
        return err
    }

    if err = cat.Wait(); err != nil {
        return err
    }

    fDiff.StandardiseData(fileOut, toListUpdateFolderPath, list.Name)

The above works fine. The problem comes when I try to append a new ele to the array. I have a seperate function which creates a new file from db content which is then added to the applicableReductions slice.

func RetrieveDomainsFromDB(collection *Collection, listName, outputPath string) error {
    domains, err := domainReviews.GetDomainsForList(listName)
    if err != nil {
        return err
    }

    if len(domains) < 1 {
        return ErrNoDomainReviewsForList
    }

    fh, err := os.OpenFile(outputPath, os.O_RDWR, 0774)
    if err != nil {
        fh, err = os.Create(outputPath)
        if err != nil {
            return err
        }
    }
    defer fh.Close()
    _, err = fh.WriteString(strings.Join(domains, "
"))
    if err != nil {
        return err
    }

    return nil
}

If I call the above function and append the filePath to the applicableReduction slice, it is in there but doesnt get called by cat.

To clarify, when I put the following where it says BROKE CODE GOES HERE:

    if dbSource {
        err = r.RetrieveDomainsFromDB(collection, ToListName, filePath)
        if err != nil {
                return err
                continue
            }
      }

The filepath can be seen when doing fmt.Println(applicableReductions) but the content of the files contents are not seen in the cat output file.

I thought perhaps a delay in the file being written so i tried adding a time.wait, tis didnt help. However the solution I found was to sort the slice, e.g this code above the call to exec cat solves the problem but I dont know why:

sort.Strings(applicableReductions)

I have confirmed all files present on both successful and unsucessful runs the only difference is without the sort, the content of the final appended file is missing

An explanation from a go-pro out there would be very much appreciated, let me know if you need more info, debug - happy to oblige to understand

UPDATE It has been suggested that this is the same issue as here: Golang append an item to a slice, I think I understand the issue there and I'm not saying this isnt the same but I cannot see the same thing happenning - the slice in question is not touched from outside the main function (e.g. no editing of the slice in RetrieveDomainsFromDB function), I create the slice before a loop, append to it within a loop and then use it after the loop - Ive added an example at the top to show how the slice is built - please could someone clarify where this slice is being copied if this is the case

  • 写回答

1条回答 默认 最新

  • dongpeng7744 2016-05-09 11:56
    关注

    UPDATE AND CLOSE Please close question - the issue was unrelated to the use of a string slice. Turns out that I was reading from the final output file before bufio-writer had been flushed (at end of function before defer flush kicked in on function return)

    I think the sorting was just re-arranging the problem so I didnt notice it persisted or possibly giving some time for the buffer to flush. Either way sorted now with a manual call to flush.

    Thanks for all help provided

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据