需求:旧系统数据库 图片存的是进制。数据有13w条(历史原因)。需要把图片进制转换对应的图片保存到本地 新系统保存图片地址。。现在写一个小程序需要转换旧系统图片数据 winfrom
while (_isWhile) { sql= txtSql.Text.Replace(row, _nextRow).Replace(pagesize, txtRow.Text); Logging.Instance.WriteEnqueue(null, sql); var dt = GetImgData(sql); if (dt == null) { //没有数据自动终止循环 _isWhile = false; lblMsg.Text = "执行完成"; Logging.Instance.WriteEnqueue(null, lblMsg.Text); return ; } for (int i = 0; i < dt.Rows.Count; i++) {
//文件名 var imgName = dt.Rows[i][fileName];
//图片进制
var stream = dt.Rows[i][fileStream]; if (string.IsNullOrEmpty(stream.ToString())) { Logging.Instance.WriteEnqueue(null, imgName + "对应列数据为空"); continue; } byte[] imagebytes = (byte[])stream; var filename = path + "\\" + imgName + ".jpg"; //问题出现在这里 如何解决呢? using (MemoryStream ms = new MemoryStream(imagebytes)) { Bitmap bmpt = new Bitmap(ms); bmpt.Save(filename, ImageFormat.Jpeg); } GC.Collect(); Thread.Sleep(20); _indexSuccess++; } _whileCout++; _nextRow = (_whileCout * int.Parse(txtRow.Text)).ToString(); if (!string.IsNullOrEmpty(txtRowStrar.Text)) { _nextRow = (_whileCout * int.Parse(txtRow.Text)+int.Parse(txtRowStrar.Text)).ToString(); } lblMsg.Text = "当前循环次数"+ _whileCout; GC.Collect(); Thread.Sleep(1000); }
目前是分批读取数据 。但是这里
Bitmap 这块这样写我知道也有问题 不停的创建对象。 内存溢出。如何解决呢?
解决code:
_indexSuccess = 0; BtnImg.Enabled = false; if (BtnImgVerification()) return; Logging.Instance.CreateFile(txtPath.Text); lblMsg.Text = "程序执行中......."; Task.Factory.StartNew(() => { ExceptionsHelp.Instance.ExecuteVoidFunc(() => { var dr = DbHelperSql.ExecuteReader(txtSql.Text); var ms = new MemoryStream(); while (dr.Read()) { var imgName = dr[txtFileName.Text]; var stream = dr[txtFileStream.Text]; if (string.IsNullOrEmpty(stream.ToString())) { Logging.Instance.WriteEnqueue(null, imgName + "对应列数据为空"); continue; } byte[] imagebytes = (byte[])stream; var filename = txtPath.Text + "\\" + imgName + ".jpg"; ms.Write(imagebytes, 0, imagebytes.Length); using (FileStream fsWrite = new FileStream(filename, FileMode.Append)) { fsWrite.Write(imagebytes, 0, imagebytes.Length); }; ms.Position = 0; _indexSuccess++; } ms.Dispose(); ms.Close(); dr.Close(); GC.Collect(); Logging.Instance.WriteEnqueue(null, _indexSuccess.ToString()); MessageBox.Show(_indexSuccess.ToString()); }, "BtnImg_Click", () => { Method(BtnImg, x => x.Enabled = true); }); });
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- Sorting 3 numbers without branching [closed]
- How to maintain order of key-value in DataFrame sa
- Graphics.DrawImage() - Throws out of memory except
如果不存在格式转换去掉Bitmap;
Using(DbConnection)
{
while(DbReader().Read())
{
var buffer = 读取byte[]列;
File.WriteAllBytes("文件名",buffer);
}
}
以上方法比较最简洁和轻量。
多半作用域之类的出问题。
你的数据有13万条,这样就要循环13万次,然后你Bitmap bmpt = new Bitmap(ms); 创建了13万次。有13万个对象占用了内存。我的建议把bmpt定义在for循环外部.循环内部重用对象。在编码的时候很多时候遇到这种情况,应该在循环外部定义对象。
Bitmap bmpt = new Bitmap();
for(xxxx)
{
bmpt.xxx = ms
}
是datatable的问题.
你把循环放外面.给表加一个是否已保存字段.
while(select count(1) from 表 where 已保存=0)
{
select top 1 * from 表 where 已保存=0
保存到文件中
update 已保存=1 where id=上面取到的id
}
Bitmap 也要放在 using 中