sqllite数据库方式与系统方式访问大量小文件的速度对比

背景:项目中有许多小文件时,系统对小文件的访问开销较大,比较慢;此时尝试将小文件合并成大文件,并将每个小文件的索引信息(比如起始位置与结束位置)存入数据库中,通过数据库访问小文件可能能够减小时间开销。
使用sqllite数据库,在linux下装好数据库、java、相应的数据库jdbc的jar包,开始测试:

Step 1:将小文件合并成大文件,并将索引写入数据库中:

import java.sql.;
import java.io.
;
public class FileCombine
{
public static void main( String args[] )
{
Connection connection = null;
Statement stmt = null;
try {
Class.forName(“org.sqlite.JDBC”);
connection=DriverManager.getConnection(“jdbc:sqlite:test1.db”);
System.out.println(“是否成功连接pg数据库”+connection);
String FileOut="/home/jojo/sqllite/1.txt";//输出路径
BufferedWriter bw=new BufferedWriter(new FileWriter(FileOut));
//读取目录下的每个文件或者文件夹,并读取文件的内容写到目标文字中去
File[] list = new File("/mnt/shared/sample_data/data").listFiles();
//File[] list = new File("/home/jojo/hello/test").listFiles();
int fileCount = 0,location=0;
for(File file : list)
{
if(file.isFile())
{
stmt = connection.createStatement();
//System.out.println(file.getName());
fileCount++;
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
location++;
}
String sql = “INSERT INTO date (id,filename,file_index) VALUES(”+fileCount+",’"+file.getName()+"’,"+location+");";
stmt.executeUpdate(sql);
stmt.close();
br.close();
}
}
bw.close();
connection.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
}
}

Step 2:将小文件的文件名取出存在txt里,之后访问要用

· import java.io.*;
public class Getname {

public static  void  main(String[] args) throws IOException {

 try {


    String FileOut="/home/jojo/name2.txt";

    BufferedWriter bw=new BufferedWriter(new FileWriter(FileOut));

  //读取目录下的每个文件或者文件夹,并读取文件的内容写到目标文字中去

    File[] list = new File("/mnt/shared/sample_data/data").listFiles();

  
    for(File file : list)

    {

        if(file.isFile())

        {
       	//System.out.println(file.getName());
            
          //  BufferedReader br = new BufferedReader(new FileReader(file));
            String line=file.getName();
	bw.write(line);
	bw.newLine();

        }

    }

    bw.close();


}catch (Exception e) {

        e.printStackTrace();

}

}

}

Step 3:测试系统直接访问时间(大致用file.exist()的时间代表,不知道有没有更好且简便的办法)和使用数据库访问的时间(用从数据库中取出索引的时间表示),测试点为100到10000间以100为步长、10000到1300000间以10000为步长,将测试结果写入database_data.txt、system_data.txt:

import java.io.;
import java.sql.
;
import java.util.Random;

public class Test {

public static  void  main(String[] args) throws IOException {
Connection connection = null;
    Statement stmt = null;
BufferedWriter bw1=new BufferedWriter(new FileWriter("system_data.txt"));
BufferedWriter bw2=new BufferedWriter(new FileWriter("database_data.txt"));
int FILENUM=1329182;
    int N=100 ;
 try {
 	Class.forName("org.postgresql.Driver");
	connection= DriverManager.getConnection("jdbc:sqlite:test1.db");
	System.out.println("是否成功连接pg数据库"+connection);
	Random r =new Random(System.currentTimeMillis());
 	while(N<FILENUM){

		String[] s=new String[N];
		File file = new File("name2.txt");//此文件存着小文件名
		
		FileReader fileReader = new FileReader(file);
		LineNumberReader reader = new LineNumberReader(fileReader);
		int k=0;
		for(int i=0;i<N;i++){
			int a = r.nextInt(FILENUM);
		//System.out.println(a);
			int line=0;
			while(true){
				if(a==line){
					s[k]=reader.readLine();
					k++;
					break;
				}
				line++;
			}
		}
		reader.close();
		fileReader.close();

//system test time
long timeStart = System.currentTimeMillis();
for(int j=0;j<N;j++){
File file1 = new File("/mnt/shared/sample_data/data/"+s[j]);
file1.exists();
//file1.close();
}
long timeEnd = System.currentTimeMillis();
//System.out.println(“fopen花费:” + (timeEnd - timeStart) + “ms”);
String line=String.valueOf(timeEnd - timeStart);
bw1.write(line);
bw1.newLine();
//database method test time
stmt = connection.createStatement();
timeStart = System.currentTimeMillis();

  		for(int idx=0;idx<N;idx++){ 
				//stmt.executeUpdate("SELECT index from merge_data where filename LIKE 'db151010.abj';");
			//System.out.println(s[idx]);
			stmt.executeQuery("select file_index from date where filename = '"+s[idx]+"';");
			//rs.next();
			//rs.getInt("index");							
			//int res=rs.getInt("index");
		}
		timeEnd = System.currentTimeMillis();
		stmt.close();
		line=String.valueOf(timeEnd - timeStart);
		bw2.write(line);
		bw2.newLine(); 
		if(N<10000){
			N+=100;
		}else{
			N+=10000;
		} 		
 	}

	//System.out.println("database 花费:" + (timeEnd - timeStart) + "ms");
	bw1.close();
	bw2.close();
}catch (Exception e) {
        e.printStackTrace();
}
}

}
总结:从结果来看,sqllite(建立了b_tree索引之后)要快于system,但这样的计时方式感觉还是有许多的误差及很多欠考虑的地方,并且系统找到文件的时间也可以优化,不用java.io.*中的类表示。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值