数据结构的课设 让写一个宿舍管理系统,用java写怎么才能不用数据库存储数据,而用文件啊。。。求大神帮忙!!!!
对于一些小文件,我们可以一次性读取它的所有字节,然后一次提交到数据库
///
/// 这个方法演示了如何一次提交所有的字节。这样导致的结果是:应用程序立即需要申请等同于文件大小的内存
///
static void SubmitFileByOnce() {
string file = @"F:\功夫熊猫.rmvb";//文件大小为519MB
byte[] buffer = File.ReadAllBytes(file);
using (SqlConnection conn = new SqlConnection("server=(local);database=demo;integrated 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=demo;integrated 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=demo;integrated 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();
}
}
}
这就是个输入输出的功能,但是在做输入的时候,在输入的时候,尽量把类容转化为json格式的字符串,不能覆盖以前的,只能在后面追加,查询的时候输出,为string,把它通过JSONObject解析,放入实体类中,http://blog.csdn.net/xionglangs/article/details/50771397,解析例子,再通过操作询。
文件的话最好用xml 或者json 数据来存储比较方便。
文件的io流来存储,可以用txt文件和xml文件来存储
方法一:用txt文件来存储,用字符流来读写数据。但是这样要分割数据需要自己想办法,分割是很麻烦的,如果数据多,字符串切割很麻烦麻烦麻烦麻烦,可能麻烦到做不出。
方法二:数据用XML的形式来存储。这样会要用到dom4j,xpath,xstream等来对xml文件的标签及属性进行增删改查。这样对输入输出流的要求比较低,但是至少要学dom4j,xpath。
方法三:使用对象流。把要数据封装到一个对象。例如Sushe这个类,有number,Person[],电费等属性.然后通过对象流写到文件(好像和后缀没关系,但是习惯用.object后缀),读取的话也是用对象的输入流来读取。我觉得这个是挺方便的,缺点:你打开文件就发现文件的内容都是乱码。这个方法的文件内容是给电脑看的,不是给人看的。
如果是我的话我会用第三种方法。
可以导出为excal文件,方便阅读