///
/// 这个方法演示了如何一次提交所有的字节。这样导致的结果是:应用程序立即需要申请等同于文件大小的内存
static void SubmitFileByOnce() {
string file = @"F:\功夫熊猫.rmvb"//文件大小为519MB
byte[] buffer = File.ReadAllBytes(file)
using (SqlConnection conn = new SqlConnection("server=(local)database=demointegrated security=true")) {
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Files(FileName,FileContents) VALUES(@fileName,@fileContents)"
cmd.Parameters.AddRange(
new[]
{
new SqlParameter("@fileName",file),
new SqlParameter("@fileContents",buffer)
})
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
}
}
}
但是,上面的方法有几个问题,主要体现在如果文件比较大的话
它需要一次性很大的内存,具体数据等同于文件大小。因为File.ReadAllBytes方法是将所有字节全部读入到内存。
它会导致提交失败,就是因为数据太大了。数据库也会拒绝。
那么,我就对这个方法做了一下改进,将文件拆分为5MB一段,也就是说,此时每次申请的内存只有5MB。这就大大地提高了可用性。
/// 这个方法是将文件切分为5MB的块,每次只是提交5MB,所以可能多次提交,但内存占用就比较小
static void SubmitFileStepByStep() {
string file = @"F:\功夫熊猫.rmvb"//以这个文件为例,大小为519MB,一共需要的时间大约94秒。还是有点慢的,所以还可能需要进行压缩
FileStream fs = new FileStream(file, FileMode.Open)
byte[] buffer = new byte[5 * 1024 * 1024]
int readCount
using (SqlConnection conn = new SqlConnection("server=(local)database=demointegrated security=true"))
{
conn.Open()
while ((readCount = fs.Read(buffer, 0, buffer.Length)) >0)
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Files(FileName,FileContents) VALUES(@fileName,@fileContents)"
cmd.Parameters.AddRange(
new[]
{
new SqlParameter("@fileName",file),
new SqlParameter("@fileContents",buffer)
})
cmd.ExecuteNonQuery()
}
}
conn.Close()
}
}
这样的话,有一个后果就是一个文件,可能在数据库中会有多条记录。所以在读取的时候,我们需要对其进行合并
static void DownloadFile() {
string file = @"F:\功夫熊猫.rmvb"
string destfile = @"E:\Temp\Temp.wmv"
using (SqlConnection conn = new SqlConnection("server=(local)database=demointegrated security=true"))
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT FileContents FROM Files WHERE FileName=@fileName"
cmd.Parameters.AddRange(
new[]
{
new SqlParameter("@fileName",file),
})
conn.Open()
SqlDataReader reader = cmd.ExecuteReader()
FileStream fs = new FileStream(destfile, FileMode.Append, FileAccess.Write)
while (reader.Read())
{
byte[] buffer = (byte[])reader[0]
fs.Write(buffer, 0, buffer.Length)
}
fs.Close()
reader.Close()
conn.Close()
}
}
}
Java注册用户MySQL储存文件可以放在MySQL数据库中,即使用MySQL中的BLOB(Binary Large Object)类型来存储文件。首先,需要创建一个存储文件的字段,类型为BLOB。然后,使用Java代码将文件读取到字节数组中,最后使用PreparedStatement对象将字节数组插入到数据库中。