10万张照片一起转base64时,内存不足

10万张照片一起转base64时,内存不足,后面的就无法编码。


void start(string dir, string dir64)
        {
            string base64;
            int cnt = 0;
            int fileno = 0;
            if (!textBox1.Text.Equals(""))
                fileno = int.Parse(textBox1.Text.ToString());
            DirectoryInfo d = new DirectoryInfo(dir);
            FileSystemInfo[] fsinfos = d.GetFileSystemInfos();

            FileInfo myfile = new FileInfo(dir64 + "\\base64_" + fileno.ToString() + ".txt");
            StreamWriter sw = myfile.CreateText();
            FileInfo myfileerror = new FileInfo(dir64 + "\\base64_error.txt");
            StreamWriter sw2 = myfileerror.CreateText();
            foreach (FileSystemInfo fsinfo in fsinfos)
            {
                cnt++;
                if (cnt % 10000 == 0)
                {
                    sw.Flush();
                    sw.Close();
                    fileno++;
                    myfile = new FileInfo(dir64 + "\\base64_" + fileno.ToString() + ".txt");
                    sw = myfile.CreateText();
                    GC.Collect();
                }
                if (fsinfo is DirectoryInfo)     //判断是否为文件夹
                {
                    start(fsinfo.FullName, dir64);//递归调用
                }
                else
                {
                    try
                    {
                        base64 = ImageFile2Base64(fsinfo.FullName, fsinfo.Name);//输出文件的全部路径
                        sw.WriteLine(cnt.ToString() + "," + fsinfo.FullName + "," + base64);
                        
                    }
                    catch (Exception e)
                    {
                        sw2.WriteLine(cnt.ToString() + "," + fsinfo.FullName + ",error:"+e.ToString());
                    }
                }
                label3.Text = "已处理" + cnt.ToString() + "条";
            }
            sw.Close();
            sw2.Close();
        }

可以在每次编码10000张照片时,将编码结果写入文件,然后清空内存,再继续编码下一批照片。

无法看到ImageFile2Base64方法,所以只能从你展示的代码看

你展示的代码最大一块其实是写日志,那么请直接用专有日志工具写日志比如 log4net,Nlog这样的东西写。

当然就代码调试来说个人建议,请把写日志操作先全部注销掉。就只调试ImageFile2Base64方法看看。(经验来说,大概率在这个方法里,毕竟常规代码是 Convert.ToBase64String(buffer),把文件全读进buffer这里消耗的内存最大

我随手找个直接流式编码的代码,这个内存开销小点

 public static void EncodeBase64File(string filein, string fileout)
        {
            try
            {
                using (FileStream fs = File.Open(fileout, FileMode.Create))
                using (var cs = new CryptoStream(fs, new ToBase64Transform(), CryptoStreamMode.Write))
                using (var fi = File.Open(filein, FileMode.Open))
                {
                    fi.CopyTo(cs);
                }
            }
            catch (Exception ex)
            {
                Utils.Log.Warn("EncodeBase64File failed with " + ex.ToString());
            }
        }


另外标题有些过了,这个循环是一张一张转换,并不是10w个一起转换。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^