2 qq 25694101 qq_25694101 于 2016.03.01 11:53 提问

java写宿舍管理系统要求用文件存储数据

数据结构的课设 让写一个宿舍管理系统,用java写怎么才能不用数据库存储数据,而用文件啊。。。求大神帮忙!!!!

6个回答

qq_33631095
qq_33631095   2016.03.01 13:59
已采纳

对于一些小文件,我们可以一次性读取它的所有字节,然后一次提交到数据库

///
/// 这个方法演示了如何一次提交所有的字节。这样导致的结果是:应用程序立即需要申请等同于文件大小的内存
///
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();
   }

}
}

但是,上面的方法有几个问题,主要体现在如果文件比较大的话

  1. 它需要一次性很大的内存,具体数据等同于文件大小。因为File.ReadAllBytes方法是将所有字节全部读入到内存。

  2. 它会导致提交失败,就是因为数据太大了。数据库也会拒绝。

那么,我就对这个方法做了一下改进,将文件拆分为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();
   }

}
}

xionglangs
xionglangs   Rxr 2016.03.01 12:00

这就是个输入输出的功能,但是在做输入的时候,在输入的时候,尽量把类容转化为json格式的字符串,不能覆盖以前的,只能在后面追加,查询的时候输出,为string,把它通过JSONObject解析,放入实体类中,http://blog.csdn.net/xionglangs/article/details/50771397,解析例子,再通过操作询。

rui888
rui888   Ds   Rxr 2016.03.01 13:21

文件的话最好用xml 或者json 数据来存储比较方便。

zqr772791008
zqr772791008   2016.03.01 14:24

文件的io流来存储,可以用txt文件和xml文件来存储

ChaoBaby94
ChaoBaby94   2016.03.01 14:52

方法一:用txt文件来存储,用字符流来读写数据。但是这样要分割数据需要自己想办法,分割是很麻烦的,如果数据多,字符串切割很麻烦麻烦麻烦麻烦,可能麻烦到做不出。
方法二:数据用XML的形式来存储。这样会要用到dom4j,xpath,xstream等来对xml文件的标签及属性进行增删改查。这样对输入输出流的要求比较低,但是至少要学dom4j,xpath。
方法三:使用对象流。把要数据封装到一个对象。例如Sushe这个类,有number,Person[],电费等属性.然后通过对象流写到文件(好像和后缀没关系,但是习惯用.object后缀),读取的话也是用对象的输入流来读取。我觉得这个是挺方便的,缺点:你打开文件就发现文件的内容都是乱码。这个方法的文件内容是给电脑看的,不是给人看的。
如果是我的话我会用第三种方法。

oDeviloo
oDeviloo   2016.03.01 14:54

可以导出为excal文件,方便阅读

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!