filedb

FileDB - A C# database to store files
FileDB is a free, fast, lightweight C# (v3.5) DLL project to store, retrive and delete files using a single file container on disk. Ideal for store small, medium or big files without databases and keep organized on a single disk file.


Update 2015-01-24

Try LiteDB, my new NoSql database with file stream support for C#. http://www.litedb.org

FileDB - Project Description

FileDB is a free, fast, lightweight C# (v3.5) DLL project to store, retrieve and delete files using a single archive file as a container on disk. It's ideal for storing files (all kind, all sizes) without databases and keeping them organized on a single disk file.

News

  • First stable version was launched
  • Improvements on concurrent write access
  • New method: Export - Export all files to a directory

Let's see how to use FileDB with static helper methods.

    using Numeria.IO;

    var pathDB = @"C:\Temp\MyDB.fdb";

    // Creating an empty FileDB archive
FileDB.CreateEmptyFile(pathDB); // Store file from input stream
var info = FileDB.Store(pathDB, "MyFileName.jpg", inputStream);
// -or- store directly from the file itself
var info = FileDB.Store(pathDB, @"C:\Temp\MyPhoto.jpg"); // The 'info' variable returned contains information about your file (generated GUID, filename, file-length, mime-type)
var fileGuid = info.ID; // Reading file inside FileDB and writing it on an output stream (also available to write it directly to a file)
var info = FileDB.Read(pathDB, fileGuid, outputStream); // Deleting a file
var ok = FileDB.Delete(pathDB, fileGuid);

FileDB Methods

  • CreateEmptyFile - Create an empty data file archive
  • Store - Store from file/stream to the data file
  • Read - Search a fileID and restore it to output file/stream
  • Delete - Delete a file
  • ListFiles - List all files inside the archive
  • Shrink - Reorganize archive removing unused disk space
  • Export - Export files inside archive to a directory

All operations have a static method helper or can be used from a FileDB instance.

ASP.NET MVC Example

Below is a basic example to store/retrieve/delete information in a ASP.NET MVC Controller

    private string pathDB = @"C:\Temp\MvcDemo.fdb";

    // Uploading a file
[HttpPost]
public ActionResult Upload()
{
HttpPostedFileBase file = Request.Files[0] as HttpPostedFileBase; if (file.ContentLength > 0)
FileDB.Store(pathDB, file.FileName, file.InputStream); return RedirectToAction("Index");
} // Download
[HttpGet]
public ActionResult Download(string id)
{
// Using a classic way to download a file, instead of FileContentResult mode.
// Optimizing for big files. Your webserver will not consume CPU/Memory to download this file (even very large files) using (var db = new FileDB(pathDB, FileAccess.Read))
{
var info = db.Search(Guid.Parse(id)); Response.Buffer = false;
Response.BufferOutput = false;
Response.ContentType = info.MimeType;
Response.AppendHeader("Content-Length", info.FileLength.ToString());
Response.AppendHeader("content-disposition", "attachment; filename=" + info.FileName); db.Read(info.ID, Response.OutputStream); return new EmptyResult();
}
}

Why?

Well, all web developers already had this problem: "I need to store same user files (photos, documents, ...) and I need to save them on my web server. But where? File system or database?" (See some discussion in http://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay#3756)
The problem is: the database was not designed to store files. ADO.NET doesn't have a good method to work with streams (only byte[]). For small files (less then 100K) it works very nice. But what happens with a 10Mb file? 100Mb? It's terrible! The solution: work on filesystem!
The filesystem has a problem too: what if my user wants to upload 300 files? And what if I have 2000 users? You will have thousands of files to backup and manage, and this will be a pain.
My idea: a single archive (or a single archive per user) to store only user uploaded files. I use the SQL Server database to store the ID file reference (GUID) and FileDB does the rest of the job, storing and managing the files and bytes.

How FileDB works?

FileDB was designed to be fast, very simple, file-based and works with all file sizes. FileDB doesn't consume lots of memory because it works only with streams (no byte[]). The data structure is built with two kinds of pages: IndexPage and DataPage.
- The IndexPage stores information about the file descriptor and it's organized in a binary tree structure.
- The DataPage stores the file bytes.
Both pages have 4096 bytes (plus 100 bytes to file header). Each page has its own header to store information about the data inside the page.
You can delete a file inside the archive and the empty data pages will be used on next insert. Or you can shrink database to get your non-used bytes.
FileDB caches (in memory) only index pages, to be faster on a second search.

Limitations

I've made many tests to check performance and limitations with all file sizes. To protect against many clients changing data on same archive, FileDB uses read share mode. This way many users can search/read simultaneously but only one user can write (store/delete) at a time. FileDB class also implements IDisposable so you can use it inside a using code.

    using(var db = new FileDB(pathDB, FileAccess.ReadWrite))
{
db.Store(@"C:\Temp\MyPhoto.jpg");
}

The data size limitations are based on .NET MaxValue constants. FileDB works with UInt32 (4 bytes unsigned), which limits each file to 4GB and the database to 16TB (4096 Pages * UInt32.MaxValue).

Future

  1. I intend to create a windows client application to explore the contents of a FileDB database. It will be a useful tool to manage files inside a database.
  2. Create a compressed data page in which data can be stored in a zip mode.
  3. Any other suggestions?

Contribute

Please, feel free to help and contribute with this project adding you comments, issues or bugs found.

FileDb的更多相关文章

  1. mysql_建立索引的优缺点 #转自Starzm#

    建立索引的优缺点: 为什么要创建索引呢? 这是因为,创建索引可以大大提高系统的性能.         第一.通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性.         第二.可以大大加 ...

  2. python基础-装饰器

    一.什么是装饰器 装饰器本质就是函数,功能是为其他函数附加功能 二.装饰器遵循的原则 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 三.实现装饰器的知识储备 装饰器=高阶函数+函数嵌套 ...

  3. socketserver模块写的一个简单ftp程序

    一坨需求... 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 (cd) ...

  4. 浅析MongoDB数据库的海量数据存储应用

    [摘要]当今已进入大数据时代,特别是大规模互联网web2.0应用不断发展及云计算所需要的海量存储和海量计算发展,传统的关系型数据库已无法满足这方面的需求.随着NoSQL数据库的不断发展和成熟,可以较好 ...

  5. 【转】MySQL外键约束On Delete、On Update各取值的含义

    转载地址:http://hi.baidu.com/jxqlovejava/item/3d2cc5b5d689917c244b0920 ‍ 先看On Delete属性,可能取值如上图为:No Actio ...

  6. 在peopletools里面测试文件上传

    Using the PeopleTools Test Utilities Page Select selectPeopleTools, then selectUtilities, then selec ...

  7. MySQL外键约束On Delete、On Update各取值的含义

    主键.外键和索引的区别?   主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...

  8. Java基于文件的对象存储

    工作中经常需要处理对象的处理,有的时候还需要将对象保存到文件中做持久化. 特别是当不能使用数据库的时候就特别需要一个简单的对象集合的增删改查操作, 于是就有了下面这个文件DB的工具类 package ...

  9. 利用whoosh对mongoDB的中文文档建立全文检索

    1.建立索引 #coding=utf-8 from __future__ import unicode_literals __author__ = 'zh' import sys,os from wh ...

随机推荐

  1. 定义一个Map集合,key和value不规定类型,任意放入数据,用keySet()和 entrySet()两种方式遍历出Map集合的数据

    package com.lanxi.demo1_1_1; import java.util.HashMap; import java.util.Iterator; import java.util.M ...

  2. 将字符串类型的出生日期转为int类型的年龄

    public static int getAgeByBirthday(String s) { Date birthday = null; SimpleDateFormat format = new S ...

  3. firefox 屏蔽Backspace按键的后退功能

    直接上图

  4. Java与C/C++有什么区别?

    (1)Java为解释型语言,其运行过程为:程序源代码经过Java编译器编译成字节码,然后由JVM解释执行.而C/C++为编译型语言,源代码经过编译和链接生成可执行的二进制代码,因此,Java的执行速度 ...

  5. 关于redis实现分布式锁

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  6. python网络编程(UDP+广播)

    UDP广播案例,一端发送,多端接受: 发送端: # UDP广播案例 from socket import * from time import sleep # 设定目标地址 dest=('176.21 ...

  7. 启动fiddler导致浏览器无法上网的解决方法

    1. 开发fiddler,进入Tools->Fiddler Tools,按照如图3部配置,即可实现无法上网的问题. 2. 见图1: 3.见图2: 4.见图3. 4. 完成以上配置后,重启fidd ...

  8. Sublime使用及配置C编译器

    一.环境配置 在安装了MinGW+Gcc的基础上做如下设置—— 新建编译系统c.sublime-build: { "cmd" : ["gcc", "$ ...

  9. holer实现外网访问本地网站

    外网访问本地网站 本地搭建了网站,只能在局域网内访问,怎样从公网也能访问内网网站? 本文将介绍使用holer实现的具体步骤. 1. 准备工作 1.1 安装并启动网站服务端 默认搭建的网站服务端端口是8 ...

  10. web 自定义标签

    Web Components 标准非常重要的一个特性是,它使开发者能够将HTML页面的功能封装为 custom elements(自定义标签).而自定义标签的好处,就是在大型web开发的时候,可以封装 ...