定时任务华为obs上传文件

使用框架:abp vnext

需求:定时从数据库取数据生成csv文件上传obs

在后台作业者模块新建一个定时任务并注册

记得一定要注册!

一开始笔者是想从本地生成文件,将内容写进去文件后上传,再删除清理内存:

var now = DateTime.Now.ToString("yyyMMdd");
string qianzhui = "reuse_detail_t";
string fileName = qianzhui + now + ".csv";
string filePath = Directory.GetCurrentDirectory() + @"/Upload/";
if (!Directory.Exists(filePath))
{
     //不存在,则创建
     Directory.Delete(filePath);
}
FileStream aFile = new FileStream(filePath + fileName, FileMode.OpenOrCreate);

using (StreamWriter sw = new StreamWriter(aFile, Encoding.UTF8))
{
     foreach (var item in datas)
     {
          StringBuilder stringBuilder = new StringBuilder();
          stringBuilder.Append(item.Id.ToString() + "|");
          ///拼接字符串。。。
          sw.WriteLine(stringBuilder.ToString());
      }
}
HuaWeiOBS.PutObjet("bucketName", "objKey", aFile);

但此时上传文件会抛出异常

Cannot access a closed Stream

没错!文件流写完就关闭了,读取不了 ,于是只能把上传的引用放在这个地方

using (StreamWriter sw = new StreamWriter(aFile, Encoding.UTF8))
{
     foreach (var item in datas)
     {
          StringBuilder stringBuilder = new StringBuilder();
          stringBuilder.Append(item.Id.ToString() + "|");
          ///拼接字符串。。。
          sw.WriteLine(stringBuilder.ToString());
      }
    HuaWeiOBS.PutObjet("bucketName", "objKey", aFile);
}

做到这里其实已经差不多了,但是!此做法并没有清理生成的文件,还得去清除它,再加一个:

        private void DeleteFile()
        {
            string filePath = Directory.GetCurrentDirectory() + @"/Upload/";
            if (Directory.Exists(filePath))
            {
                foreach (string f in Directory.GetFileSystemEntries(filePath))
                {
                    if (File.Exists(f))
                    {
                        //如果有子文件删除文件
                        File.Delete(f);
                    }
                }
                //删除空文件夹
                Directory.Delete(filePath);
            }
        }

 在定时任务执行时清理它:

using (var uow = LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>().Begin())
{
    DeleteFile();
    var oeHwDataManager = ServiceProvider.GetRequiredService<OeHwDataManager>();
    await oeHwDataManager.UploadObsFileAsync();
    await uow.CompleteAsync();
}

此方法第一次执行时没有任何问题,但是第二次执行时就会抛出异常:

System.IO.IOException
The process cannot access the file 'D:\wwwroot\Upload\xxx.csv' because it is being used by another process.

没错,按着这意思来看得关闭程序才能删除这个文件了,但这是不现实的;

所以笔者在想有没有办法能绕过写入文件,再读取文件流这一个步骤,就是说不用生成本地文件,我们直接生成一个流,将内容写进去,再以流形式上传obs。后来经过询问朋友和baidu,终于有了解决方案,使用内存流去进行此操作,但需要注意,MemoryStream是会占用服务器性能的,所以说,请按情况使用这方法。话不多说,直接贴代码:

private async Task CreateCsvFileAsync(List<HwData> datas)
{
    byte[] bytes;
    using (MemoryStream ms = new())
    {
        using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
        {
            foreach (var item in datas)
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append(item.Id.ToString() + "|");
                ///拼接字符串。。。
                sw.WriteLine(stringBuilder.ToString());
            }
            //放在这里的原因是,出了StreamWriter后,也会抛异常Cannot access a closed Stream
            //不要问我为什么出了这个using就关闭了,求你了,百度吧
            bytes = new byte[ms.Length];
            ms.Read(bytes, 0, bytes.Length);
        }
    }
    HuaWeiOBS.PutObjet("bucketName", "objKey", new MemoryStream(bytes));
}

从数据库取出来的数据在这里我们已经转换成了byte[]对象,使用此对象一般不会有什么问题,也不会抛出奇奇怪怪的异常啦,后续将此对象转化为流就可以上传了,并且可以多次上传,比如需要“备份”,end。

如果对你有帮助,就请点个赞吧!

如果你需要引用此文章的内容,请标记出处哦!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值