• RTMP协议视频平台EasyDSS通过Golang实现超大文件复制功能备份文件方法


    在 EasyDSS 的开发过程中,由于有用户在使用过程中出现过误删的操作,所以我们需要对用户上传的视频进行备份,防止用户误删除,此过程需要对文件进行复制。

    常用的文件复制功能,直接采用 go 官方库提供的 io.Copy() 方法进行实现。

    nBytes, err := io.Copy(destination, source)
    

    以上方法适用于小文件的复制,对于超大文件,比如 500MB 甚至 1GB 以上文件的复制就会出现问题。

    io.Copy() 方法的基本逻辑是,一次性将源文件全部读取到内存中,然后从内存中将数据写入到新的文件中。对于较大的文件,比如读取 2GB 大小的视频文件,一次性就会消耗 2GB 的内存,如果电脑内存本身就很小,此时程序就会提供内存不够。因此针对较大文件不应该直接调用此方法。

    对于较大文件的复制操作,应该每次都读取很小的数据,比如1024 字节,写入到新的文件中。然后再次读取文件,写入新文件,直到将所有的数据写入到新文件中。

    func Copy(src, dst string) (int64, error) {
       sourceFileStat, err := os.Stat(src)
       if err != nil {
          return 0, err
       }
     
       if !sourceFileStat.Mode().IsRegular() {
          return 0, fmt.Errorf("%s is not a regular file", src)
       }
     
       source, err := os.Open(src)
       if err != nil {
          return 0, err
       }
       defer source.Close()
     
       destination, err := os.Create(dst)
       if err != nil {
          return 0, err
       }
       defer destination.Close()
       //nBytes, err := io.Copy(destination, source)
     
       nBytes := int64(0)
       buf := make([]byte, 4096)
       for {
          n, err := source.Read(buf)
          if err != nil && err != io.EOF {
             return 0, err
          }
          if n == 0 {
             break
          }
     
          if _, err := destination.Write(buf[:n]); err != nil {
             return 0, err
          }
     
          // 更新写入的数量
          nBytes = nBytes + int64(n)
       }
     
       return nBytes, err
    }
    

     

    当读取文件时,遇到 EOF 标志,代表文件读取完毕。上述方法中的核心代码如下。

     
    nBytes := int64(0)
    buf := make([]byte, 4096)
    for {
       n, err := source.Read(buf)
       if err != nil && err != io.EOF {
          return 0, err
       }
       if n == 0 {
          break
       }
     
       if _, err := destination.Write(buf[:n]); err != nil {
          return 0, err
       }
     
       // 更新写入的数量
       nBytes = nBytes + int64(n)
    }
    

      

    EasyDSS是TSINGSEE青犀视频研发的关于互联网视频直播/点播平台,能够接入RTMP协议摄像头及设备,并生成推流地址进行视频监控的推流直播。使用EasyDSS的用户都知道,我们提供了丰富的API接口,开发者可以自由进行二次开发,API接口详情:http://demo.easydss.com:10080/apidoc。

  • 相关阅读:
    Java-死锁
    Java使用Redis
    MySQL如何开启慢查询
    VGG
    如何使用Soft-NMS实现目标检测并提升准确率
    非极大值抑制(NMS)
    迁移学习与fine-tuning有什么区别
    Keras-在预训练好网络模型上进行fine-tune
    Kotlin——初级篇(六):空类型、空安全、非空断言、类型转换等特性总结
    Kotlin——初级篇(五):操作符与操作符重载一
  • 原文地址:https://www.cnblogs.com/easydss/p/13722489.html
Copyright © 2020-2023  润新知