精华内容
下载资源
问答
  • Android不需要文件存储权限将文件保存至手机,Android不需要文件存储权限将文件保存至手机
  • 实现基于文件存储的日程安排应用,数据文件可以保存在机身内存或者SD卡中。通过单击增加图标打开新增加活动界面,通过单击保存按钮将活动内容写入到文件中,并返回前页,点击删除图标,可以删除该活动。
  • android studio实现文件存储和sharedPreference存储,以QQ登陆为例,将登录的用户名和密码保存到后台,有2种方式
  • Android本地数据存储中的文件存储,写入,重写和删除Android中.txt格式的文件
  • Android之文件数据存储 一、文件保存数据介绍 ...所有的Android设备都有两个文件存储区域:“内部”和“外部”存储。这篇文章主要是将数据存储,所以在“内部”存储区域存储文件。 二、使用方法 1. 向文件写
  • Android Studio文件存储

    千次阅读 2018-08-23 08:57:47
    其实安卓文件的操作和java在pc环境下的操作并无二致,之所以需要单独讲解是因为安卓系统提供了不同于pc的访问文件系统根路径的api,同时对一个应用的私有文件做了统一的管理。根据我的经验,初学者在这部分感到很...

    原文链接:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0923/1557.html

     

     

    其实安卓文件的操作和java在pc环境下的操作并无二致,之所以需要单独讲解是因为安卓系统提供了不同于pc的访问文件系统根路径的api,同时对一个应用的私有文件做了统一的管理。根据我的经验,初学者在这部分感到很容易混淆内部存储和外部存储两个概念。

    相对路径和绝对路径

    在java中,关于相对路径和绝对路径是这样解释的,如果你很熟悉这部分以下灰色文字可以跳过:

    绝对路径是指书写文件的完整路径,例如d:\java\Hello.java,该路径中包含文件的完整路径d:\java以及文件的全名Hello.java。使用该路径可以唯一的找到一个文件,不会产生歧义。但是使用绝对路径在表示文件时,受到的限制很大,且不能在不同的操作系统下运行,因为不同操作系统下绝对路径的表达形式存在不同。

    相对路径是指书写文件的部分路径,例如\test\Hello.java,该路径中只包含文件的部分路径\test和文件的全名Hello.java,部分路径是指当前路径下的子路径,例如当前程序在d:\abc下运行,则该文件的完整路径就是d:\abc\test。使用这种形式,可以更加通用的代表文件的位置,使得文件路径产生一定的灵活性。

    在Eclipse项目中运行程序时,当前路径是项目的根目录,例如工作空间存储在d:\javaproject,当前项目名称是Test,则当前路径是:d:\javaproject\Test。在控制台下面运行程序时,当前路径是class文件所在的目录,如果class文件包含包名,则以该class文件最顶层的包名作为当前路径。

    这是java在多数操作系统中这样操作,很显然是要我们尽可能的使用相对路径,但是在安卓中,其实多数情况下我们都是使用的绝对路径。为什么呢?注意上面说到相对路径是以当前项目所在路径为当前路径,但在安卓中我们是不可能在项目所在路径目录下做任何操作的,因为普通java中我们的项目创建于服务器(pc也算是服务器),运行于服务器,我们当然能在服务器操作自己的文件目录。但是安卓开发中,我们的项目一般是创建于自己工作的电脑,而运行于手机,既然apk已经运行于手机了,那项目就已经部署到手机上了,应该以apk在手机上的位置来确定相对路径,但我们好像们没有办法操作这个路径的,因为apk是在system目录下,就算可以操作,在这个目录下存取文件也是没有意义的,比如我写一个相册程序,图片肯定是放在外部存储中,而如果我要保存一个应用的一些设置数据,我是放在内部存储的data目录下,因此其实在安卓文件管理中,我们都是在操作绝对路径。

    File类

    操作一个文件(读写,创建文件或者目录)是通过File类来完成的,这个操作和java中完全一致。

    外部存储external storage和内部存储internal storage

    1.内部存储:

    注意内部存储不是内存。内部存储位于系统中很特殊的一个位置,如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。从技术上来讲如果你在创建内部存储文件的时候将文件属性设置成可读,其他app能够访问自己应用的数据,前提是他知道你这个应用的包名,如果一个文件的属性是私有(private),那么即使知道包名其他应用也无法访问。内部存储空间十分有限,因而显得可贵,另外,它也是系统本身和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机也就无法使用了。所以对于内部存储空间,我们要尽量避免使用。Shared Preferences和SQLite数据库都是存储在内部存储空间上的。内部存储一般用Context来获取和操作。

    getFilesDir()获取你app的内部存储空间,相当于你的应用在内部存储上的根目录。

    如果是要创建一个文件,如下

    1

    File file = newFile(context.getFilesDir(), filename);

    安卓还为我们提供了一个简便方法 openFileOutput()来读写应用在内部存储空间上的文件,下面是一个向文件中写入文本的例子:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    String filename = "myfile";

    String string = "Hello world!";

    FileOutputStream outputStream;

    try{

    outputStream = openFileOutput(filename, Context.MODE_PRIVATE);

    outputStream.write(string.getBytes());

    outputStream.close();

    catch(Exception e) {

    e.printStackTrace();

    }

    内部存储的其他一些操作:

    A.列出所有的已创建的文件,这个可能不容易想到,Context居然有这样的方法。

    1

    2

    3

    4

    String[] files = Context.fileList();

    for(String file : files) {

    Log.e(TAG, "file is "+ file);

    }

    B.删除文件,能创建就要能够删除,当然也会提供了删除文件的接口,它也非常简单,只需要提供文件名

    1

    2

    3

    4

    5

    if(Context.deleteFile(filename)) {

    Log.e(TAG, "delete file "+ filename + " sucessfully“);

    } else {

    Log.e(TAG, "failed to deletefile " + filename);

    }

    C.创建一个目录,需要传入目录名称,它返回 一个文件对象用到操作路径

    1

    2

    File workDir = Context.getDir(dirName, Context.MODE_PRIVATE);

    Log.e(TAG, "workdir "+ workDir.getAbsolutePath();


    总结一下文件相关操作,可以得出以下三个特点:
    1. 文件操作只需要向函数提供文件名,所以程序自己只需要维护文件名即可;
    2. 不用自己去创建文件对象和输入、输出流,提供文件名就可以返回File对象或输入输出流
    3. 对于路径操作返回的都是文件对象。

     

    2.外部存储:

    最容易混淆的是外部存储,如果说pc上也要区分出外部存储和内部存储的话,那么自带的硬盘算是内部存储,U盘或者移动硬盘算是外部存储,因此我们很容易带着这样的理解去看待安卓手机,认为机身固有存储是内部存储,而扩展的T卡是外部存储。比如我们任务16GB版本的Nexus 4有16G的内部存储,普通消费者可以这样理解,但是安卓的编程中不能,这16GB仍然是外部存储。

    所有的安卓设备都有外部存储和内部存储,这两个名称来源于安卓的早期设备,那个时候的设备内部存储确实是固定的,而外部存储确实是可以像U盘一样移动的。但是在后来的设备中,很多中高端机器都将自己的机身存储扩展到了8G以上,他们将存储在概念上分成了"内部internal" 和"外部external" 两部分,但其实都在手机内部。所以不管安卓手机是否有可移动的sdcard,他们总是有外部存储和内部存储。最关键的是,我们都是通过相同的api来访问可移动的sdcard或者手机自带的存储(外部存储)。

    外部存储虽然概念上有点复杂,但也很好区分,你把手机连接电脑,能被电脑识别的部分就一定是外部存储。

     

    关于外部存储,我觉得api中在介绍Environment.getExternalStorageDirectory()方法的时候说得很清楚:

    don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.

    看不懂没关系,其实跟我说的意思差不多,只是觉得说得比较形象,不知道是我的表述问题,还是英文在逻辑解释方面比汉语强,因为白话文其实是被阉割的汉语。

    外部存储中的文件是可以被用户或者其他应用程序修改的,有两种类型的文件(或者目录):

    1.公共文件Public files:文件是可以被自由访问,且文件的数据对其他应用或者用户来说都是由意义的,当应用被卸载之后,其卸载前创建的文件仍然保留。比如camera应用,生成的照片大家都能访问,而且camera不在了,照片仍然在。

    如果你想在外存储上放公共文件你可以使用getExternalStoragePublicDirectory()

    1

    2

    3

    4

    5

    6

    7

    8

    9

    public File getAlbumStorageDir(String albumName) {

    // Get the directory for the user's public pictures directory.

    File file = newFile(Environment.getExternalStoragePublicDirectory(

    Environment.DIRECTORY_PICTURES), albumName);

    if(!file.mkdirs()) {

    Log.e(LOG_TAG, "Directory not created");

    }

    returnfile;

    }

    在上面的代码中我们创建获得了存放picture的目录,并且新创建一个albumName文件。

    如果你的api 版本低于8,那么不能使用getExternalStoragePublicDirectory(),而是使用Environment.getExternalStorageDirectory(),他不带参数,也就不能自己创建一个目录,只是返回外部存储的根路径。

    2.私有文件Private files:其实由于是外部存储的原因即是是这种类型的文件也能被其他程序访问,只不过一个应用私有的文件对其他应用其实是没有访问价值的(恶意程序除外)。外部存储上,应用私有文件的价值在于卸载之后,这些文件也会被删除。类似于内部存储。

    创建应用私有文件的方法是Context.getExternalFilesDir(),如下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    public File getAlbumStorageDir(Context context, String albumName) {

    // Get the directory for the app's private pictures directory.

    File file = newFile(context.getExternalFilesDir(

    Environment.DIRECTORY_PICTURES), albumName);

    if(!file.mkdirs()) {

    Log.e(LOG_TAG, "Directory not created");

    }

    returnfile;

    }

    上面的代码创建了一个picture目录,并在这个目录下创建了一个名为albumName的文件,Environment.DIRECTORY_PICTURES其实就是字符串picture。

    所有应用程序的外部存储的私有文件都放在根目录的Android/data/下,目录形式为/Android/data/<package_name>/

    如果你的api 版本低于8,那么不能使用getExternalFilesDir(),而是使用Environment.getExternalStorageDirectory()获得根路径之后,自己再想办法操作/Android/data/<package_name>/下的文件。

    也就是说api 8以下的版本在操作文件的时候没有专门为私有文件和公共文件的操作提供api支持。你只能先获取根目录,然后自行想办法。

     

    在使用外部存储之前,你必须要先检查外部存储的当前状态,以判断是否可用。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    boolean mExternalStorageAvailable = false;

    boolean mExternalStorageWriteable = false;

    String state = Environment.getExternalStorageState();

    if(Environment.MEDIA_MOUNTED.equals(state)) {

    // We can read and write the media

    mExternalStorageAvailable = mExternalStorageWriteable = true;

    } elseif(Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {

    // We can only read the media

    mExternalStorageAvailable = true;

    mExternalStorageWriteable = false;

    else{

    // Something else is wrong. It may be one of many other states, but all we need

    //  to know is we can neither read nor write

    mExternalStorageAvailable = mExternalStorageWriteable = false;

    }

     

    最后为了弄清楚getFilesDir,getExternalFilesDir,getExternalStorageDirectory,getExternalStoragePublicDirectory等android文件操作方法,我将这些方法的执行结果打印出来,看看到底路径是啥样,在activity中执行以下代码:

    1

    2

    3

    4

    5

    6

    Log.i("codecraeer""getFilesDir = "  + getFilesDir());

    Log.i("codecraeer""getExternalFilesDir = "  + getExternalFilesDir("exter_test").getAbsolutePath());

    Log.i("codecraeer""getDownloadCacheDirectory = "  + Environment.getDownloadCacheDirectory().getAbsolutePath());

    Log.i("codecraeer""getDataDirectory = "  + Environment.getDataDirectory().getAbsolutePath());

    Log.i("codecraeer""getExternalStorageDirectory = "  + Environment.getExternalStorageDirectory().getAbsolutePath());

    Log.i("codecraeer""getExternalStoragePublicDirectory = "  + Environment.getExternalStoragePublicDirectory("pub_test"));

    在log中看到如下结果:

    从log中我们可以看到外部存储根目录在我手机(nexus 3)上是/storage/emulated/0,奇怪的是在有些手机上同样的代码却是下面的情况:

    部存储根目录为/mnt/sdcard.

    在网上搜了下好像是说三星手机就是这样。

    展开全文
  • Android开发——理解文件存储

    千次阅读 2016-10-16 13:20:32
    一、内部存储和外部存储的概念在Android中,我们可以把数据存储在SharedPreferences、内部存储、外部存储、SQLite数据库和网络上。其中内部存储指的是设备内存,一般存储私有数据;外部存储是共享的,可以用来存储...

    在开发过程中,我们经常会遇到读写文件,比如缓存图片、网页,下载视频、图片等。这就带来一个问题,针对于不同的情形,我们应该将文件置于何处?

    一、内部存储和外部存储的概念

    在Android中,我们可以把数据存储在SharedPreferences、内部存储、外部存储、SQLite数据库和网络上。其中内部存储指的是设备内存,一般存储私有数据;外部存储是共享的,可以用来存储公有数据。

    1.1、什么是内部存储和外部存储

    所有Android设置都有两个文件存储区域:内部和外部存储。这些名称在Android早期产生,当时大多数设备都提供内置的非易失性内存(内存存储),以及移动存储介质,比如SD卡(外部存储)。一些设备将永久性存储空间划分为内部和外部分区,即便没有移动存储介质,也始终有两个存储空间,并且无论外部存储设备是否可移动,API的行为均一致。
    内部存储
    - 始终可用
    - 默认情况下只有自己应用可以访问此处保存的文件
    - 当用户卸载应用时,系统会从内存存储中删除应用的所有文件
    当希望用户或其他应用均无法访问文件时,内存存储是最佳选择。
    外部存储
    - 并非始终可用,因为用户可能会采用USB存储的形式装载外部存储或者移除
    - 全局可读的
    - 当用户卸载应用时,只有getExternalFilesDir()目录下的文件会被系统删除
    对于无需访问限制以及希望与其他应用共享或允许用户使用电脑访问文件时,外部存储是最佳选择。
    ==尽管应用默认安装在内部存储中,但可以在mainfest文件中指定android:installLocation属性,这样应用便可以安装在外部存储中。当APK非常大且外部存储空间大于内存内存时,用户更青睐这个选择。==

    1.2、使用内部存储

    在内部存储中保存文件时,可以通过调用以下两种方法之一作为File的相应目录:
    getFilesDir()
    返回表示应用的内部目录的File
    getCacheDir()
    返回表示应用临时缓存文件的内部目录。
    另外,如果需要缓存某些文件,应该调用createTempFile()方法。例如,以下方法从URL提取文件名并在应用中以该名称创建文件:

    public File getTempFile(Context context, String url) {
        File file;
        try { 
            String fileName = Uri.parse(url).getLastPathSegment();
            file = File.createTempFile(fileName, null, context.getCacheDir());
        } catch (IOException e) {
            // Error while creating file 
        } 
        return file;
    } 

    ==应用的内部存储设备目录由应用在Android文件系统特定位置中的包名指定。在技术上,如果将文件模式设置为可读,另一个应用可以读取该内部文件。但是,另一个应用需要知道包名和文件名。==
    除了上面的介绍,还有方法可以保存文件到内部存储中,
    1)调用openFileOutput方法并传入文件名和操作模式,返回FileOutputStream对象。
    2)调用write()方法写入内容
    3)调用close()方法关闭流
    举个例子:

    String FILENAME = "hello_file";
    String string = "hello world!";
    
    FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
    fos.write(string.getBytes());
    fos.close();

    MODE_PRIVATE会创建文件(或者替换相同名称的文件)并且使之为应用私有。其他模式有MODE_APPEND、MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。
    ==MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE从API 17开始废弃。从Android N开始,如果再使用会抛出SecurityException异常。这意味着在Android N之后的版本不能通过“file:”URI分享文件了,会导致FileUriExposedException抛出。如果你的应用需要和别的应用分享私有文件,需要使用FileProvider,具体可参考分享文件==
    从内部存储中读取文件也分为三步:
    1)调用openFileInput方法并传入文件名,返回FileInputStream。
    2)调用read()方法读取字节
    3)调用close()关闭输入流

    1.2.1、保存缓存文件

    如果你想缓存某些数据,而不是一直持有,你需要调用getCacheDir()方法打开一个代表应用暂时保存缓存文件的内部目录。
    当设备的内部存储容量不足时,Android会删除这些缓存文件来恢复控件。然而,你不应该依赖于系统来删除缓存文件。你应该始终自己管理缓存文件并且有责任让它们限制在一个范围,比如1MB。当用于卸载应用时,这些文件会被移除。
    其他有用的方法
    getFilesDir()
    返回使用openFileOutput(String,int)方法创建文件的目录
    getDir()
    创建(或打开现有)的内部存储空间中的目录。
    deleteFile()
    删除内部存储中的文件
    fileList()
    返回关联当前应用的私有文件

    1.3、使用外部存储

    每一个Android兼容的设置支持共享外部存储来保存文件。但是这个存储是可移除的(比如SD卡)或者一个内置存储(不能移除的)。存储在外部存储的文件是共享的,并且用户可以通过将其连接到电脑上传输文件时可以修改。
    ==如果用户将外部存储挂载到电脑上或移除,那么外部存储就变成不可获得了。所有的应用可以读写保存在外部存储上的文件并且用户可以移除。==

    1.3.1、使用作用域目录访问

    在Android 7.0及其以后,如果需要获取外部存储上的指定目录,使用作用域目录访问。作用域目录访问简化了应用如何获取标准的外部存储目录,比如Pictures目录。具体可以参考使用作用域目录访问

    1.3.2、获得外部存储

    为了在外部存储上读写文件,应用需要声明READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE系统权限。比如:

    <manifest ...>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        ...
    </manifest>

    如果同时需要读写文件,你只需要声明WRITE_EXTERNAL_STORAGE权限即可,因为这个权限隐式地包含了读权限。
    ==从Android 4.4开始,如果只是读应用私有的文件,那么这些权限不是必需的==

    1.3.3、检查媒体的可用性

    在使用外部存储之前,需要调用getExyernalStorageState()方法检查外部存储是否可用。外部存储可能会被挂载到电脑上,或被移除,或只读,或其他状态。下面是一段检查可用性的代码:

    /* Checks if external storage is available for read and write */ 
    public boolean isExternalStorageWritable() { 
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true; 
        } 
        return false; 
    } 
    
    /* Checks if external storage is available to at least read */ 
    public boolean isExternalStorageReadable() { 
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) ||
            Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true; 
        } 
        return false; 
    } 

    getExternalStorageState()方法返回多种状态,比如外部存储是否可共享,是否消失,是否移除等。

    1.3.4、保存可以分享给其他应用的文件

    通常,如果要创建别的应用可以获得的文件,一般存储在公共位置,这样别的应用可以获得,用户也可以执行复制等操作。当这样做的时候,你需要使用共享公共目录,比如Music/,Pictures/,和Ringtones/等。
    为了获得相应的公共目录,调用getExternalStoragePublicDirectory()方法,并传入你想要目录的类型,比如DIRECTORY_MUSIC,DIRECTORT_PICTURES,DIRECTORY_RINGTONES或者其他。通过将文件保存在相应的媒体目录下,系统的媒体扫描器可以在系统中分类文件(比如,铃声出现在铃声设置中,而不是音乐)。举个例子,下面是创建一个公有的相册目录:

    public File getAlbumStorageDir(String albumName) {
        // Get the directory for the user's public pictures directory. 
        File file = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), albumName);
        if (!file.mkdirs()) {
            Log.e(LOG_TAG, "Directory not created");
        } 
        return file;
    }

    1.3.5、保存应用私有的文件

    如果你在保存的文件不希望给别的应用使用(比如应用自己的音效),你需要调用getExternalFilesDir()方法获取外部存储上的私有存储目录。这个方法也需要一个type参数来指定子目录的类型(比如DIRECTORY_MOVIES)。如果你不需要指定媒体目录,传入null参数可以获得私有目录的根目录。
    从Android 4.4开始,读写应用的私有目录不需要声明READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限。所以,你可以在声明权限时使用maxSdkVersion参数,如下:

    <manifest ...>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                         android:maxSdkVersion="18" />
        ...
    </manifest>

    ==当用户卸载应用时,这个目录和其内容会被删除。同时,系统媒体扫描器不会读这些目录下的文件,因此不可以通过MediaStore获得。因此,不应该使用该目录保存照片等信息,这些文件应该保存在公有目录中==
    现在,有很多设备既有内置的外置存储,又可以插入SD卡。当这样的设置运行在Android 4.3及其低版本中,getExternalFilesDir()方法只会得到内置的外部存储,应用不能读写SD卡。从4.4开始,你可以通过getExternalFilesDirs()获取两个目录,返回一个文件数组。数组中第一个元素是主共享外部存储,一般都应先使用该目录除非它满了。如果想在4.3及其低版本中获取目录,需要使用支持库中的静态方法,ContextCompat。getExternalFilesDirs(),这个方法也会返回一个File数组,但是在Android4.3及其低版本中,只有一个元素。
    ==尽管getExternalFilesDir()和getExternalFilesDirs()得到的目录不会被MediaStore扫描到,但是其他包含READ_EXTERNAL_STORAGE权限的应用可以获得这些文件。如果你需要严格限制文件的获得,那么应该保存在内部存储中==

    1.3.6、保存缓存文件

    为了打开外部存储上保存缓存文件的目录,应该调用getExternalCacheDir()方法。如果应用被卸载,这些文件会自动被删除。
    类似于上面提到的ContextCompat.getExternalFilesDirs()方法,你也可以在第二块外部存储中调用ContextCompat.getExternalCacheDirs获取缓存目录。

    二、查询可用空间

    如果事先知道保存文件的大小,那么就可以查出是否有足够的可用空间来存储文件,就不需要调用getFreeSpace()或getTotalSpace()方法引起IOException了。这些方法分别提供目前的可用空间和总空间。
    但是,系统并不保证你可以写入与getFreeSpace()一样多的字节。如果返回的数字比要保存的文件大出几MB,或者文件系统所占用的空间不到90%,那么可以安全操作,否则,不应写入存储。
    ==在保存文件之前,无需检查可用空间量。可以尝试立刻写入文件,然后在IOException出现时将其捕获。如果你不知道确切空间量,可能需要那么做。==

    三、总结

    从上面可以看出,如果需要将文件保存在内部存储中,都需要调用Context的方法。无论是getFilesDir()还是getCacheDir,亦或是getFileOutput()和getFileInput()方法,都是Context的方法;但是如果需要获取外部存储的目录,那么都需要使用Environment提供的方法,比如getExternalFilesDir()等方法。

    展开全文
  • 盘点分布式文件存储系统

    千次阅读 2021-02-08 22:14:23
    在项目的数据存储中,结构化数据通常采用关系型数据库,非结构化数据(文件)的存储就有很多种方式,服务器本地存储、Nas挂载、ftp等等,今天就来盘点一下,分布式文件存储系统。

    在项目的数据存储中,结构化数据通常采用关系型数据库,非结构化数据(文件)的存储就有很多种方式,服务器本地存储、Nas挂载、ftp等等,今天就来盘点一下,分布式文件存储系统。

    一、分布式存储简介

    1、什么是分布式存储

    在开始介绍分布式存储之前,先了解一下,非分布式的存储方案。

    在单机时代,将文件直接存储在服务部署的服务器上——

    • 直连存储(DAS):存储和数据直连,拓展性、灵活性差。

    为了扩展,将文件和服务分离,通过网络连接——

    • 中心化存储(NAS、SAN):设备类型丰富,通过网络互连,具有一定的拓展性,但是受到控制器能力限制,拓展能力有限。同时,设备到了生命周期要进行更换,数据迁移需要耗费大量的时间和精力。

    DAS、SAN,还是NAS? 中小企业数据存储探究

    分布式存储:通过网络使用企业中的每台机器上的磁盘空间,并将这些分散的存储资源构成一个虚拟的存储设备,数据分散的存储在企业的各个角落。

    图5 分布式存储示意图

    2、分布式存储的优势

    可扩展:分布式存储系统可以扩展到数百甚至数千个这样的集群大小,并且系统的整体性能可以线性增长。

    高可用性:在分布式文件系统中,高可用性包含两层,一是整个文件系统的可用性,二是数据的完整和一致性

    低成本:分布式存储系统的自动容错和自动负载平衡允许在成本较低服务器上构建分布式存储系统。此外,线性可扩展性还能够增加和降低服务器的成本。

    弹性存储: 可以根据业务需要灵活地增加或缩减数据存储以及增删存储池中的资源,而不需要中断系统运行

    二、主流分布式文件存储系统

    目前主流的分布式文件系统有:GFS、HDFS、Ceph、Lustre、MogileFS、MooseFS、FastDFS、TFS、GridFS等。

    1、GFS(Google File System)

    ​ Google公司为了满足本公司需求而开发的基于Linux的专有分布式文件系统。尽管Google公布了该系统的一些技术细节,但Google并没有将该系统的软件部分作为开源软件发布。

    2、HDFS(Hadoop Distributed File System)

    ​ HDFS(Hadoop Distributed File System)是 Hadoop 项目的一个子项目。是 Hadoop 的核心组件之一, Hadoop 非常适于存储大型数据 (比如 TB 和 PB),其就是使用 HDFS 作为存储系统. HDFS 使用多台计算机存储文件,并且提供统一的访问接口,像是访问一个普通文件系统一样使用分布式文件系统。

    HDFS架构

    3、TFS(Taobao FileSystem)

    ​ TFS是一个高可扩展、高可用、高性能、面向互联网服务的分布式文件系统,主要针对海量的非结构化数据,它构筑在普通的Linux机器 集群上,可为外部提供高可靠和高并发的存储访问。TFS为淘宝提供海量小文件存储,通常文件大小不超过1M,满足了淘宝对小文件存储的需求,被广泛地应用在淘宝各项应用中。它采用了HA架构和平滑扩容,保证了整个文件系统的可用性和扩展性。同时扁平化的数据组织结构,可将文件名映射到文件的物理地址,简化 了文件的访问流程,一定程度上为TFS提供了良好的读写性能。

    4、Lustre

    Lustre是一个大规模的、安全可靠的,具备高可用性的集群文件系统,它是由SUN公司开发和维护的。该项目主要的目的就是开发下一代的集群文件系统,可以支持超过10000个节点,数以PB的数据量存储系统。目前Lustre已经运用在一些领域,例如HP SFS产品等。

    5、 MooseFS

    MooseFS是一款相对小众的分布式文件系统,不需要修改上层应用接口即可直接使用,支持FUSE的操作方式,部署简单并提供Web界面的方式进行管理与监控,同其他分布式操作系统一样,支持在线扩容,并进行横向扩展。MooseFS还具有可找回误操作删除的文件,相当于一个回收站,方便业务进行定制;同时MooseFS对于海量小文件的读写要比大文件读写的效率高的多。

    但MooseFS的缺点同样明显,MFS的主备架构情况类似于MySQL的主从复制,从可以扩展,主却不容易扩展。短期的对策就是按照业务来做切分,随着MFS体系架构中存储文件的总数上升,Master Server对内存的需求量会不断增大。并且对于其单点问题官方自带的是把数据信息从Master Server同步到Metalogger Server上,Master Server一旦出问题Metalogger Server可以恢复升级为Master Server,但是需要恢复时间。目前,也可以通过第三方的高可用方案(heartbeat+drbd+moosefs)来解决 Master Server 的单点问题。

    6、MogileFS

    由memcahed的开发公司danga一款perl开发的产品,目前国内使用mogielFS的有图片托管网站yupoo等。MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上。

    7. FastDFS

    是一款类似Google FS的开源分布式文件系统,是纯C语言开发的。FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

    8、GlusterFS

    开源分布式横向扩展文件系统,可以根据存储需求快速调配存储,内含丰富的自动故障转移功能,且摈弃集中元数据服务器的思想。适用于数据密集型任务的可扩展网络文件系统,具有可扩展性、高性能、高可用性等特点。gluster于2011年10月7日被Red Hat收购。

    9、 GridFS

    MongoDB是知名的NoSQL数据库,GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件,GridFS的基本原理是将文件保存在两个Collection中,一个保存文件索引,一个保存文件内容,文件内容按一定大小分成若干块,每一块存在一个Document中,这种方法不仅提供了文件存储,还提供了对文件相关的一些附加属性(比如MD5值,文件名等等)的存储。文件在GridFS中会按4MB为单位进行分块存储。

    在这里插入图片描述

    三、分布式文件系统的对比

    1、整体对比

    文件系统开发者开发语言开源协议易用性适用场景特性缺点
    GFSGoogle不开源
    HDFSApacheJavaApache安装简单,官方文档专业化存储非常大的文件大数据批量读写,吞吐量高;一次写入,多次读取,顺序读写难以满足毫秒级别的低延时数据访问;不支持多用户并发写相同文件;不适用于大量小文件
    Ceph加州大学圣克鲁兹分校Sage WeilC++LGPL安装简单,官方文档专业化单集群的大中小文件分布式,没有单点依赖,用C编写,性能较好基于不成熟的btrfs,自身也不够成熟稳定,不推荐在生产环境使用
    TFSAlibabaC++GPL V2安装复杂,官方文档少跨集群的小文件针对小文件量身定做,随机IO性能比较高;实现了软RAID,增强系统的并发处理能力及数据容错恢复能力;支持主备热倒换,提升系统的可用性;支持主从集群部署,从集群主要提供读/备功能不适合大文件的存储;不支持POSIX,通用性较低;不支持自定义目录结构与文件权限控制;通过API下载,存在单点的性能瓶颈;官方文档少,学习成本高
    LustreSUNCGPL复杂,而且严重依赖内核,需要重新编译内核大文件读写企业级产品,非常庞大,对内核和ext3深度依赖
    MooseFSCore Sp. z o.o.CGPL V3安装简单,官方文档多,且提供Web界面的方式进行管理与监控大量小文件读写比较轻量级,用perl编写,国内用的人比较多对master服务器有单点依赖,性能相对较差
    MogileFSDanga InteractivePerlGPL主要用在web领域处理海量小图片key-value型元文件系统;效率相比mooseFS高很多不支持FUSE
    FastDFS国内开发者余庆CGPL V3安装简单,社区相对活跃单集群的中小文件系统无需支持POSIX,降低了系统的复杂度,处理效率更高;实现了软RAID,增强系统的并发处理能力及数据容错恢复能力;支持主从文件,支持自定义扩展名;主备Tracker服务,增强系统的可用性不支持断点续传,不适合大文件存储;不支持POSIX,通用性较低;对跨公网的文件同步,存在较大延迟,需要应用做相应的容错策略;同步机制不支持文件正确性校验;通过API下载,存在单点的性能瓶颈
    GlusterFSZ RESEARCHCGPL V3安装简单,官方文档专业化适合大文件,小文件性能还存在很大优化空间无元数据服务器,堆栈式架构(基本功能模块可以进行堆栈式组合,实现强大功能),具有线性横向扩展能力;比mooseFS庞大由于没有元数据服务器,因此增加了客户端的负载,占用相当的CPU和内存;但遍历文件目录时,则实现较为复杂和低效,需要搜索所有的存储节点,不建议使用较深的路径
    GridFSMongoDBC++安装简单通常用来处理大文件(超过16M)可以访问部分文件,而不用向内存中加载全部文件,从而保持高性能;文件和元数据自动同步

    2、 特性对比

    文件系统数据存储方式集群节点通讯协议专用元数据存储点在线扩容冗余备份单点故障跨集群同步FUSE挂载访问接口
    HDFS文件私有协议(TCP)占用MDS支持存在不支持支持不支持POSIX
    Ceph对象/文件/块私有协议(TCP)占用MDS支持支持存在不支持支持POSIX
    Lustre对象私有协议(TCP)/ RDAM(远程直接访问内存)双MDS支持不支持存在未知支持POSIX/MPI
    MooseFS私有协议(TCP)占用MFS支持支持存在不支持支持POSIX
    MogileFS文件HTTP占用DB支持不支持存在不支持不支持不支持POSIX
    FastDFS文件/块私有协议(TCP)支持支持不存在部分支持不支持不支持POSIX
    GlusterFS文件/块私有协议(TCP)/RDAM(远程直接访问内存)支持支持不存在支持支持POSIX
    TFS文件私有协议(TCP)占用NS支持支持存在支持未知不支持POSIX

    什么是POSIX?

    POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),也就是Unix下应用程序共同遵循的一种规范。支持POSIX的应用程序意味着在各个Unix系统间提供了跨平台运行的支持。

    四、选型参考

    • 适合做通用文件系统的有:Ceph,Lustre,MooseFS,GlusterFS;

    • 适合做小文件存储的文件系统有:Ceph,MooseFS,MogileFS,FastDFS,TFS;

    • 适合做大文件存储的文件系统有:HDFS,Ceph,Lustre,GlusterFS,GridFS;

    • 轻量级文件系统有:MooseFS,FastDFS;

    • 简单易用,用户数量活跃的文件系统有:MooseFS,MogileFS,FastDFS,GlusterFS;

    • 支持FUSE挂载的文件系统有:HDFS,Ceph,Lustre,MooseFS,GlusterFS。



    参考:

    【1】:分布式文件系统对比与选型参考

    【2】:只知道HDFS和GFS?你其实并不懂分布式文件系统

    【3】:分布式存储主流框架

    【4】:如果要设计个分布式文件系统,该从哪些方面考虑?

    【5】: 常见分布式文件存储介绍、选型比较、架构设计

    【6】:分布式文件系统对比与选型参考

    【7】:中小企业存储:DAS、NAS和SAN的选择

    【8】:从DAS到分布式存储,存储形式总结

    展开全文
  • 使用C++实现STL文件的读取,同时以相应的数据结构进行存储。显示面片数,去重后的节点数,运行时间
  • java 文件存储

    千次阅读 2018-07-15 18:58:08
    在开发中上传文件存储是个问题,而一般小应用开发会选择服务器本地目录做为存储地址,通过保存文件的相对路径来获取文件,在应用不要求高可用的情况下这是一种普遍的方案。 问题: 在每次更新Java版本时,都需要将...

    一、小应用存储方案

    在开发中上传文件存储是个问题,而一般小应用开发会选择服务器本地目录做为存储地址,通过保存文件的相对路径来获取文件,在应用不要求高可用的情况下这是一种普遍的方案。

    问题: 在每次更新Java版本时,都需要将文件目录做一次备份,不然直接将打包好的war包替换原来的版本时可能会丢失文件(有时可能会直接删除原来的版本目录然后在将新版本放到tomcat的webapps目录)。

    解决方案: 使用 linux (windows的快捷方式) 的软连接方式将文件目录存储在tomcat webapps文件目录之外,这样应用程序只需要读取软连接的目录即可上传文件到真正的文件目录地址,而读取文件还是从软连接的目录读取,这样整个应用目录被删除文件也不会丢失。这里需要提一下在tomcat中读取软连接文件需要在context.xml文件配置一个allowLinking属性(只要添加属性即可,不要删除其他配置)。

    <!--tomcat 5 6 7-->    
    <Context allowLinking="true"/> 
    
    <!--tomcat 8-->    
    <Context>  
      <Resources allowLinking="true"/> 
    </Context>
    
    

    二、云存储方案

    随着文件系统规模越来越大,以及对应用的高可用与高并发需求。特别在应用需要快速迭代时可以选择比较成熟云存储解决方案。

    云存储是在云计算(cloud computing)概念上延伸和发展出来的一个新的概念,是指通过集群应用、网格技术或分布式文件系统等功能,应用存储虚拟化技术将网络中大量各种不同类型的存储设备通过应用软件集合起来协同工作,共同对外提供数据存储和业务访问功能的一个系统。所以云存储可以认为是配置了大容量存储设备的一个云计算系统。

    现国内较成熟的云存储有阿里云的Oss,腾讯的Cos (本人并没有使用过) 即其他云服务提供商,云计算的基本特点是对外提供的海量、安全、低成本、高可靠的云存储服务。您可以通过本文档提供的简单的REST接口,在任何时间、任何地点、任何互联网设备上进行上传和下载数据。

    基于大存储优势,您可以搭建出各种多媒体分享网站、网盘、个人和企业数据备份等基于大规模数据的服务。

    缺点: 运营会产生额外的费用。

    优点: 开发成本低,可以配置cdn加速网络...

    三、分布式文件系统方案

    常见的分布式文件系统有,GFS、HDFS、FastDFS等。各自适用于不同的领域。它们都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。

    1.GFS(Google File System)

    Google公司为了满足本公司需求而开发的基于Linux的专有分布式文件系统,尽管Google公布了该系统的一些技术细节,但Google并没有将该系统的软件部分作为开源软件发布。

    2.HDFS

    Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。

    3.FastDFS

    FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

    FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用
    FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

    FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。

    FastDFS原理

    FastDFS通过客户端连接tracker集群,tracker返回一个集群中可用的storage节点给客户端,客户端直接与storage连接传输文件,当storage文件保存成功并将信息同步到tracker时,storage将返回一个fileId给客户端(fileId 字段中的 group可以计算出对应服务器IP,M00是软连接文件存储的目录),客户端可以通过这个fileId直接访问到文件,也可以通过fileId下载图片。

    FastDFS集群线性扩容

    由于FastDFS通过tracker来管理存储节点,要实现线性扩容只要添加storage然后配置新的group即可,这里可以只要使用默认的负载方案(根据存储节点大小决定)将文件存储在高容量节点,注意两相同group中采取最小的节点为准。

    FastDFS冗余备份

    FastDFS文件备份根据相同的group个数来决定备份的个数,当有两个group相同,上传文件时将在另外一台机器上进行同步操作,以此类推。如果另一台机器宕机了,那将在恢复工作后继续同步。如果在新增的节点上配置已有的group,并且group已经有文件,那么新的节点也将同步已有的文件。

    FastDFS架构图
    图片来自网络

    FastDFS安装

    FastDFS具体安装请参照 https://github.com/happyfish1... 注意:在配置tracker_server时配置多个就是多节点。

    案例地址: https://github.com/tzling/fas...

    FastDFS与HDFS的区别

    定位和应用场合不一样,Hadoop的文件系统HDFS主要解决并行计算中分布式存储数据的问题,其单个数据文件通常很大,采用了分块(切分)存储的方式。

    FastDFS主要用于大中网站,为文件上传和下载提供在线服务,在负载均衡、动态扩容等方面都支持得比较好,FastDFS不会对文件进行分快(切分)存储。

    优点:高容错性能,高扩张性。

    缺点:开发成功高,配置难度较复杂。

    部分信息来自网络。

    展开全文
  • Android文件存储(一)内部存储

    万次阅读 2018-08-29 15:56:26
    内部存储空间的私有目录 路径:data/data/包名 外部存储空间的私有目录 路径:/storage/emulated/0/Android/data/包名 外部存存储空间的公共目录 路径:/storage/emulated/0...
  • 记录微信中文件传输助手文件存储位置问题。 参考手机型号:华为Mate10。 文件位于:Android\data\com.tencent.mm\MicroMsg\Download 上述位置是文档的位置,图片或视频的位置不在这。图片和视频可以去图库里查看...
  • Anaconda3修改文件存储路径

    千次阅读 2021-03-25 13:30:45
    Anaconda3修改文件存储路径1.在Anaconda Prompt 终端输入2.用记事本打开配置文件 查找c.NotebookApp.notebook_dir(ctrl+f)3.把c.NotebookApp.notebook_dir这行注释打开 后面写入自己设置的文件存储路径4.修改之后...
  • 【Linux】Linux文件文件存储

    万次阅读 2018-07-31 18:39:51
    从使用和创建文件的用户角度来看,文件是磁盘的最小存储单元,用户数据除非在文件中,否则不能保存到磁盘;从进程的角度来看,文件是一种进程可以对它进行访问的,但独立于进程而存在的数据结构,文件中的信息不会因...
  • Flutter持久化存储之文件存储

    千次阅读 2019-03-28 13:38:30
    本篇将给大家分享Flutter中的file存储功能,Flutter SDK本身已经有File相关的api,所以在Flutter中使用file存储的关键是如何获取手机中存储的目录,然后根据目录路径来创建不同的file。根据Flutter的特性,我们可以...
  • Flutter(三十)——文件存储

    千次阅读 2020-03-29 19:51:19
    前面博主介绍讲解了key-value形式的SharedPreferences的存储方式和sqflite的数据库插件的使用方式,对于手机端来说,我们还需要对文件形式的存储有一定了解。 在Flutter中已经实现了文件操作相关的API。Flutter中...
  • Python-CSV文件存储

    万次阅读 2019-04-29 17:42:39
    CSV,全称为Comma-Separated Values,中文可以叫做逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔。每条记录由字段组成,字段...
  • web选择文件保存路径

    热门讨论 2013-04-22 14:35:15
    web选择文件保存路径的方式,大致分为两种,大家可以下来了了解一下,个人表示第一种比较好用
  • qt文件保存

    千次阅读 2019-07-01 14:34:08
    void MainWindow::on_pushButtonSave_clicked() { QString fileName = QFileDialog::getSaveFileName(this, tr("保存当前日志"), ...
  • Android10.0文件存储

    千次阅读 2020-07-31 09:21:25
    从Android Q(即 Android 10)开始,应用访问外部存储的私有目录(即Context.getExternalFilesDir())不需要申请READ_EXTERNAL_STORAGEorWRITE_EXTERNAL_STORAGE权限。同时,正常情况下,就算应用有申请READ_EXTERNAL_...
  • Android 3种数据保存(SharedPreferences存储 内部文件存储 数据库存储),如项目包有问题请联系我谢谢
  • java 文件保存到本地

    万次阅读 2018-12-07 17:33:37
    private void savePic(InputStream inputStream, String fileName) { OutputStream os = null; try { String path = "D:\\testFile\\"; // 2、保存到临时文件 // 1K的数...
  • IDEA配置文件保存位置修改

    千次阅读 2021-01-19 18:27:24
    IDEA配置文件保存位置修改 JetBrains系列 默认配置文件保存在: 用户配置: C:\Users\administrator\AppData\Local\JetBrains 系统配置: C:\Users\administrator\AppData\Roaming\JetBrains 因为配置存放在C盘 重做...
  • 本次代码的环境: 运行平台: Windows Python版本: Python3.x IDE: PyCharm 一 概述 数据存储是爬虫的一个很重要的部分,爬虫爬出来的数据要不存到...基于这两个存储思想,保存形式可以动作多样,文件存储有:T...
  • pandas文件保存操作

    千次阅读 2020-03-18 11:32:02
    在使用DataFrame的to_csv保存文件的时候,会默认使用逗号作为分隔符,如果没有设置行列索引,也没有禁用行列索引保存的话,保存文件的时候,会默认加上由0开始的行列索引。 data = pd.DataFrame(np.arange(9)....
  • Android 文件保存

    千次阅读 2019-05-13 07:19:16
    所有Android设备都有两个文件存储区:“内部”和“外部”存储。这些名称来自Android的早期,大多数设备提供内置的非易失性存储器(内部存储),以及可移动存储介质,如microSD卡(外部存储)。现在,许多设备将永久...
  • Anaconda 修改文件保存路径

    千次阅读 2020-08-04 18:45:43
    输入jupyter notebook --generate-config生成配置文件~\.jupyter\jupyter_notebook_config.py 2.打开~.jupyter\jupyter_notebook_config.py 修改 #c.NotebookApp.notebook_dir = ’ ’ 为下一行 c.NotebookApp....
  • Idea 设置文件存储路径

    千次阅读 2020-04-25 15:26:21
    File–settings-systemSettins-
  • 从应用角度看块存储、文件存储、对象存储 产品和市场需求有各种相互影响的关系,但不管是哪一种,最终呈现都是产品和应用需求需要对应匹配。应用需求越多样化,市场也就划分得更加细,产品种类也就更加丰富。在...
  • Linux文件存储

    千次阅读 2016-07-29 19:25:52
    简单介绍几种Linux支持的文件系统:NFS、MINIX、MS-DOS和ext2,日志文件系统:ext3、JFS和ReiserFS,同时还有加密文件系统(CFS)和虚拟文件系统(/proc)。二、一次文件的读取过程: 用户通过输入vim fileA来打开...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,050,526
精华内容 2,020,210
关键字:

文件存储