拿到一个财务系统的备份文件,是以MSS为后缀的,分析看一下,就是一个SQL SERVER的备份文件压缩包,恢复的话,先解压再恢复就好了,开发环境:VS2010,数据库SQL SERVER 2008 R2,相关界面设计如下图。
private bool restoreFile(string TargetFile, string dataBaseName, ref string msg)
{
string rootFile = "";
msg = "";
try
{
//读取压缩文件准备解压缩
ZipInputStream inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
ZipEntry entry;
string fileDir = Application.StartupPath + "\\temp\\";
string path = fileDir;
//解压出来的文件保存路径
string rootDir = "";
//根目录下的第一个子文件夹的名称
while ((entry = inputstream.GetNextEntry()) != null)
{
rootDir = Path.GetDirectoryName(entry.Name);
//得到根目录下的第一级子文件夹的名称
if (rootDir.IndexOf("\\") >= 0)
{
rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
}
string dir = Path.GetDirectoryName(entry.Name);
//得到根目录下的第一级子文件夹下的子文件夹名称
string fileName = Path.GetFileName(entry.Name);
//根目录下的文件名称
if (dir != "")
{
//创建根目录下的子文件夹,不限制级别
if (!Directory.Exists(fileDir + "\\" + dir))
{
path = fileDir + "\\" + dir;
//在指定的路径创建文件夹
Directory.CreateDirectory(path);
}
}
else if (dir == "" && fileName != "")
{
//根目录下的文件
path = fileDir;
rootFile = fileName;
}
else if (dir != "" && fileName != "")
{
//根目录下的第一级子文件夹下的文件
if (dir.IndexOf("\\") > 0)
{
//指定文件保存路径
path = fileDir + "\\" + dir;
}
}
if (dir == rootDir)
{
//判断是不是需要保存在根目录下的文件
path = fileDir + "\\" + rootDir;
}
//解压 后缀为BAK的文件,其它不管
string fileSuffix = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));
if (fileName != String.Empty && fileSuffix.ToLower() == ".bak")
{
databaseBackupFilePath=path + "\\" + fileName;
FileStream fs = File.Create(databaseBackupFilePath);
byte[] data = new byte[2048];
int size = inputstream.Read(data, 0, data.Length);
while (size > 0)
{
fs.Write(data, 0, size);
size = inputstream.Read(data, 0, data.Length);
}
fs.Close();
}
} //end while
inputstream.Close();
}
catch (Exception ex)
{
msg = "解压缩文件错误:"+ex.Message;
return false;
}
if (databaseBackupFilePath == String.Empty)
{
msg = "文件解析错误:目标文件中没有找到数据库备份文件!";
return false;
}
//数据库变量
string strconn = "Data Source=" + shareInfo.HostIP + ";Initial Catalog=master;User ID=" + shareInfo.dbUser + ";pwd =" + shareInfo.dbPassword + "";
SqlConnection conn = new SqlConnection(strconn);
SqlCommand cmd = null;
SqlDataReader dr=null;
DataTable dt = null;
SqlDataAdapter adapter = null;
string mdf = "", log = "", sql = "";
//解析备份文件信息
try
{
sql = "restore filelistonly from disk = '" + databaseBackupFilePath + "'";
adapter = new SqlDataAdapter(sql, strconn);
dt = new DataTable();
lock (adapter)
{
adapter.Fill(dt);
}
mdf = dt.Rows[0][0].ToString();
log = dt.Rows[1][0].ToString();
}
catch (Exception ex)
{
msg = "备份文件解析错误:"+ex.Message;
return false;
}
//如果需要覆盖,则先删除已有数据库
if (overWrite)
{
//断开所有和数据库相关的连接
try
{
conn.Open();
sql = "SELECT spid FROM sysprocesses ,sysdatabases WHERE sysprocesses.dbid=sysdatabases.dbid AND sysdatabases.Name='" + dataBaseName + "'";
cmd = new SqlCommand(sql, conn);
ArrayList list = new ArrayList();
dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(dr.GetInt16(0));
}
dr.Close();
for (int i = 0; i < list.Count; i++)
{
cmd = new SqlCommand(string.Format("KILL {0}", list[i].ToString()), conn);
cmd.ExecuteNonQuery();
}
}
catch (SqlException eee)
{
msg = "恢复文件错误:" + eee.ToString();
return false;
}
finally
{
conn.Close();
}
sql = string.Format("drop database {0}", dataBaseName);
try
{
conn.Open();
cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
msg = "删除数据库错误:"+ex.Message;
return false;
}
finally
{
conn.Close();
}
}
//开始恢复文件
try
{
string dataDir = Application.StartupPath + "\\data\\";
sql = @"restore database {0} from disk = '{1}' with REPLACE, move '{2}' to '" + dataDir + "{3}.mdf',move '{4}' to '" + dataDir + "{5}.ldf'";
string restore = string.Format(sql,dataBaseName,databaseBackupFilePath, mdf, dataBaseName, log, dataBaseName);
conn.Open();
cmd = new SqlCommand(restore, conn);
cmd.CommandTimeout = 0;
cmd.ExecuteNonQuery();
//更改所有者
cmd = new SqlCommand(restore, conn);
dbHelper db = new dbHelper();
db.ExecuteNonQuery(dataBaseName, "exec sp_msforeachtable 'sp_changeobjectowner ''?'', ''dbo'''");
}
catch (Exception ex)
{
msg ="恢复数据错误:"+ ex.Message;
return false;
}
finally
{
conn.Close();
}
//删除临时文件
try
{
string tempDir = Application.StartupPath + "\\temp\\";
DirectoryInfo dir = new DirectoryInfo(tempDir);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
subdir.Delete(true); //删除子目录和文件
}
else
{
File.Delete(i.FullName); //删除指定文件
}
}
}
catch (Exception e)
{
msg = "删除临时文件错误:" + e.Message;
return false;
}
return true;
}
步骤比较清晰,解压文件->解析文件->覆盖/不覆盖已有数据库->还原到指定名称数据库。