欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android文件管理器用法详解

程序员文章站 2023-08-21 22:38:33
很久没有写东西了,鉴于某某同学文件管理器不会,这里简单介绍一下,同时写一个demon,参考了网上别人写的代码,自己也学习学习,研究研究。   首先所谓文件管理器,看起来就...

很久没有写东西了,鉴于某某同学文件管理器不会,这里简单介绍一下,同时写一个demon,参考了网上别人写的代码,自己也学习学习,研究研究。

  首先所谓文件管理器,看起来就是一个列表,列表里面是文件夹或者文件,首先把布局写出来,我想在最上方的左边显示文件的路径,右边显示该路径下的文件个数,其实还是一个遍历文件,然后用列表显示出来的问题。下面是listview,用来显示文件列表。下面是运行的效果图:

android文件管理器用法详解

主界面的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <relativelayout 
    android:id="@+id/top"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <textview 
      android:id="@+id/path"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignparentleft="true"
      android:layout_centervertical="true"
      android:textsize="@*android:dimen/list_item_size"
      android:textcolor="@android:color/white"/>
    
    <textview 
      android:id="@+id/item_count"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textsize="@*android:dimen/list_item_size"
      android:textcolor="@android:color/white"
      android:layout_alignparentright="true"
      android:layout_centervertical="true"/>
  </relativelayout>
  <view 
    android:layout_width="match_parent"
    android:layout_height="2dip"
    android:background="#09c"/>

  <linearlayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <listview 
      android:id="@+id/file_list"
      android:layout_height="match_parent"
      android:layout_width="match_parent"
      android:fadingedge="none"
      android:cachecolorhint="@android:color/transparent"/>
  </linearlayout>
</linearlayout>

首先在oncreate方法里面调用一个方法去获取布局文件里面的id:

@override
   protected void oncreate (bundle savedinstancestate) {
     super.oncreate(savedinstancestate);
     setcontentview(r.layout.file_manager);
     initview();
 }

initview之后添加apk的权限,777 表示可读可写可操作。

private void initview() {
    mlistview = (listview) findviewbyid(r.id.file_list);
    mpathview = (textview) findviewbyid(r.id.path);
    mitemcount = (textview) findviewbyid(r.id.item_count);
    mlistview.setonitemclicklistener(this);
    string apkroot = "chmod 777 " + getpackagecodepath(); 
    rootcommand(apkroot);
    file folder = new file("/");
    initdata(folder);
  } 

修改root权限的方法:

public static boolean rootcommand (string command) {
    process process = null;
    dataoutputstream os = null;
    try {
      process = runtime.getruntime().exec("su");
      os = new dataoutputstream(process.getoutputstream());
      os.writebytes(command + "\n");
      os.writebytes("exit\n");
      os.flush();
      process.waitfor();
    }
    catch (exception e) {
      return false;
    }
    finally {
      try {
        if (os != null) {
          os.close();
        }
        process.destroy();
      }
      catch (exception e) {
        e.printstacktrace();
      }
    }
    return true;
  }

完了之后我们要获取根目录下面的所有的数据,然后设置到我们的listview中让它显示出来。

private void initdata(file folder) {
    boolean isroot = folder.getparent() == null; 
    mpathview.settext(folder.getabsolutepath()); 
    arraylist<file> files = new arraylist<file>();  
    if (!isroot) {
      files.add(folder.getparentfile()); 
    }
    file[] filterfiles = folder.listfiles(); 
    mitemcount.settext(filterfiles.length + "项"); 
    if (null != filterfiles && filterfiles.length > 0) {
      for (file file : filterfiles) {
        files.add(file);
      }
    }
    mfileadpter = new filelistadapter(this, files, isroot); 
    mlistview.setadapter(mfileadpter);
  }

首先是获取当前是否是根目录,然后把文件的路径设置给我们要显示的view。

然后用一个arraylist来装我们目录下的所有的文件或者文件夹。

首先要把这个文件夹的父类装到我们的列表中去,然后把这个文件夹下的子文件都拿到,也装在列表中,然后调用adapter显示出来。既然说到了adapter, 那就看下adapter吧。

private class filelistadapter extends baseadapter {

    private context context;
    private arraylist<file> files;
    private boolean isroot;
    private layoutinflater minflater;
    
    public filelistadapter (context context, arraylist<file> files, boolean isroot) {
      this.context = context;
      this.files = files;
      this.isroot = isroot;
      minflater = layoutinflater.from(context);
    }
    
    @override
    public int getcount () {
      return files.size();
    }

    @override
    public object getitem (int position) {
      return files.get(position);
    }

    @override
    public long getitemid (int position) {
      return position;
    }
    
    @override
    public view getview (int position, view convertview, viewgroup parent) {
      viewholder viewholder;
      if(convertview == null) {
        viewholder = new viewholder();
        convertview = minflater.inflate(r.layout.file_list_item, null);
        convertview.settag(viewholder);
        viewholder.title = (textview) convertview.findviewbyid(r.id.file_title);
        viewholder.type = (textview) convertview.findviewbyid(r.id.file_type);
        viewholder.data = (textview) convertview.findviewbyid(r.id.file_date);
        viewholder.size = (textview) convertview.findviewbyid(r.id.file_size);
      } else {
        viewholder = (viewholder) convertview.gettag();
      }
      
      file file = (file) getitem(position);
      if(position == 0 && !isroot) {
        viewholder.title.settext("返回上一级");
        viewholder.data.setvisibility(view.gone);
        viewholder.size.setvisibility(view.gone);
        viewholder.type.setvisibility(view.gone);
      } else {
        string filename = file.getname();
        viewholder.title.settext(filename);
        if(file.isdirectory()) {
          viewholder.size.settext("文件夹");
          viewholder.size.settextcolor(color.red);
          viewholder.type.setvisibility(view.gone);
          viewholder.data.setvisibility(view.gone);
        } else {
          long filesize = file.length();
          if(filesize > 1024*1024) {
            float size = filesize /(1024f*1024f);
            viewholder.size.settext(new decimalformat("#.00").format(size) + "mb");
          } else if(filesize >= 1024) {
            float size = filesize/1024;
            viewholder.size.settext(new decimalformat("#.00").format(size) + "kb");
          } else {
            viewholder.size.settext(filesize + "b");
          }
          int dot = filename.indexof('.');
          if(dot > -1 && dot < (filename.length() -1)) {
            viewholder.type.settext(filename.substring(dot + 1) + "文件");
          }
          viewholder.data.settext(new simpledateformat("yyyy/mm/dd hh:mm").format(file.lastmodified()));
        }
      }
      return convertview;
    }
    
    class viewholder {
      private textview title;
      private textview type;
      private textview data;
      private textview size;
    }
  }

看下adapter的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <textview 
      android:id="@+id/file_title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textsize="25sp"
      android:textcolor="#fff000"/>
  <linearlayout 
    android:id="@+id/file_info"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <textview 
      android:id="@+id/file_size"
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:textcolor="#ffffcc"
      android:layout_weight="1"
      android:textsize="18sp"/>
    
    <textview 
      android:id="@+id/file_type"
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:textcolor="#ffffcc"
      android:layout_weight="1"
      android:gravity="right"
      android:textsize="18sp"/>
    <textview 
      android:id="@+id/file_date"
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:textcolor="#ffffff"
      android:layout_weight="1"
      android:gravity="right"
      android:textsize="18sp"/>
  </linearlayout>
</linearlayout>

列表的item项分2行显示,上面一行显示文件名

下面一行分别显示文件大小,文件类型,文件修改时间。

我们可以通过file file = (file) getitem(position);拿到item项的文件,如果是在第一个并且不再根目录我们就把第一个也就是parentfile显示为:“返回上一级”,下一行的都隐藏掉。

如果不是第一个位置,可以拿到这个文件的一系列信息。

先把string filename = file.getname();文件名拿到,显示出来。

如果这个文件是一个文件夹,就把文件的大小显示为“文件夹”,类型和修改时间隐藏掉。

如果不是一个文件夹, 可以拿到文件的长度long filesize = file.length();

根据特定的长度显示文件的大小,b, kb, mb, gb等。

然后拿到文件的类型,通过最后一个“.”之后的字符串就是该文件的类型。

通过viewholder.data.settext(new simpledateformat("yyyy/mm/dd hh:mm").format(file.lastmodified())); 设置文件的最近修改时间。

然后可以设置每个item项的点击事件,如下所示:

@override
  public void onitemclick (adapterview<?> parent, view view, int position, long id) {
    file file = (file) mfileadpter.getitem(position);
    if(!file.canread()) {
      new alertdialog.builder(this).settitle("提示").setmessage("权限不足").setpositivebutton(android.r.string.ok, new onclicklistener() {
        
        @override
        public void onclick (dialoginterface dialog, int which) {
          
        }
      }).show();
    } else if(file.isdirectory()) {
      initdata(file);
    } else {
      openfile(file);
    }
  }

如果这个文件不能读,就弹出对话框显示“权限不足”。

如果是一个文件夹,就在调用一次显示所有文件的方法:initdata(file);把这个文件夹作为参数传递下去。

如果是一个文件,就可以调用打开文件的方法打开这个文件。

如何打开文件呢?

可以根据不同的文件的后缀名找到不同的文件类型:

可以用一个二维数组把一些常用的文件类型封装起来。如下:

private final string[][] mime_maptable = {
    // {后缀名, mime类型}
    { ".3gp", "video/3gpp" }, 
    { ".apk", "application/vnd.android.package-archive" }, 
    { ".asf", "video/x-ms-asf" }, 
    { ".avi", "video/x-msvideo" },
    { ".bin", "application/octet-stream" }, 
    { ".bmp", "image/bmp" }, 
    { ".c", "text/plain" }, 
    { ".class", "application/octet-stream" },
    { ".conf", "text/plain" }, 
    { ".cpp", "text/plain" }, 
    { ".doc", "application/msword" },
    { ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, 
    { ".xls", "application/vnd.ms-excel" },
    { ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, 
    { ".exe", "application/octet-stream" },
    { ".gif", "image/gif" }, 
    { ".gtar", "application/x-gtar" }, 
    { ".gz", "application/x-gzip" }, 
    { ".h", "text/plain" }, 
    { ".htm", "text/html" },
    { ".html", "text/html" }, 
    { ".jar", "application/java-archive" }, 
    { ".java", "text/plain" }, 
    { ".jpeg", "image/jpeg" },
    { ".jpg", "image/jpeg" }, 
    { ".js", "application/x-javascript" }, 
    { ".log", "text/plain" }, 
    { ".m3u", "audio/x-mpegurl" },
    { ".m4a", "audio/mp4a-latm" }, 
    { ".m4b", "audio/mp4a-latm" }, 
    { ".m4p", "audio/mp4a-latm" }, 
    { ".m4u", "video/vnd.mpegurl" },
    { ".m4v", "video/x-m4v" }, 
    { ".mov", "video/quicktime" }, 
    { ".mp2", "audio/x-mpeg" }, 
    { ".mp3", "audio/x-mpeg" }, 
    { ".mp4", "video/mp4" },
    { ".mpc", "application/vnd.mpohun.certificate" }, 
    { ".mpe", "video/mpeg" }, 
    { ".mpeg", "video/mpeg" }, 
    { ".mpg", "video/mpeg" },
    { ".mpg4", "video/mp4" }, 
    { ".mpga", "audio/mpeg" }, 
    { ".msg", "application/vnd.ms-outlook" }, 
    { ".ogg", "audio/ogg" },
    { ".pdf", "application/pdf" }, 
    { ".png", "image/png" }, 
    { ".pps", "application/vnd.ms-powerpoint" },
    { ".ppt", "application/vnd.ms-powerpoint" }, 
    { ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
    { ".prop", "text/plain" }, 
    { ".rc", "text/plain" }, 
    { ".rmvb", "audio/x-pn-realaudio" }, 
    { ".rtf", "application/rtf" },
    { ".sh", "text/plain" }, 
    { ".tar", "application/x-tar" }, 
    { ".tgz", "application/x-compressed" }, 
    { ".txt", "text/plain" },
    { ".wav", "audio/x-wav" }, 
    { ".wma", "audio/x-ms-wma" }, 
    { ".wmv", "audio/x-ms-wmv" }, 
    { ".wps", "application/vnd.ms-works" },
    { ".xml", "text/plain" }, 
    { ".z", "application/x-compress" }, 
    { ".zip", "application/x-zip-compressed" }, 
    { "", "*/*" } 
    };

分别对应的是后缀名和对应的文件类型。

我们可以根据文件的后缀名拿到文件的mimetype类型:

private string getmimetype(file file) {
    string type = "*/*";
    string filename = file.getname();
    int dotindex = filename.indexof('.');
    if(dotindex < 0) {
      return type;
    }
    string end = filename.substring(dotindex, filename.length()).tolowercase();
    if(end == "") {
      return type;
    }
    for(int i=0; i<mime_maptable.length; i++) {
      if(end == mime_maptable[i][0]) {
        type = mime_maptable[i][1] ;
      }
    }
    return type;
  }

先遍历后缀名,如果找到,就把对应的类型找到并返回。

拿到了类型,就可以打开这个文件。

用这个intent.setdataandtype(uri.fromfile(file), type); 打开设置打开文件的类型。

如果type是*/*会弹出所有的可供选择的应用程序。

 到这里一个简易的文件管理器就成型了。

源代码:

package com.android.test;

import java.io.dataoutputstream;
import java.io.file;
import java.text.decimalformat;
import java.text.simpledateformat;
import java.util.arraylist;

import android.app.activity;
import android.app.alertdialog;
import android.content.context;
import android.content.dialoginterface;
import android.content.intent;
import android.content.dialoginterface.onclicklistener;
import android.graphics.color;
import android.net.uri;
import android.os.bundle;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.adapterview;
import android.widget.adapterview.onitemclicklistener;
import android.widget.baseadapter;
import android.widget.listview;
import android.widget.textview;
import android.widget.toast;

public class filemanager extends activity implements onitemclicklistener {
  
  private listview mlistview;
  private textview mpathview;
  private filelistadapter mfileadpter;
  private textview mitemcount;
  
  @override
  protected void oncreate (bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.file_manager);
    initview();
  }
  
  private void initview() {
    mlistview = (listview) findviewbyid(r.id.file_list);
    mpathview = (textview) findviewbyid(r.id.path);
    mitemcount = (textview) findviewbyid(r.id.item_count);
    mlistview.setonitemclicklistener(this);
    string apkroot = "chmod 777 " + getpackagecodepath(); 
    rootcommand(apkroot);
    file folder = new file("/");
    initdata(folder);
  }
  
  public static boolean rootcommand (string command) {
    process process = null;
    dataoutputstream os = null;
    try {
      process = runtime.getruntime().exec("su");
      os = new dataoutputstream(process.getoutputstream());
      os.writebytes(command + "\n");
      os.writebytes("exit\n");
      os.flush();
      process.waitfor();
    }
    catch (exception e) {
      return false;
    }
    finally {
      try {
        if (os != null) {
          os.close();
        }
        process.destroy();
      }
      catch (exception e) {
        e.printstacktrace();
      }
    }
    return true;
  }
  
  private void initdata(file folder) {
    boolean isroot = folder.getparent() == null; 
    mpathview.settext(folder.getabsolutepath()); 
    arraylist<file> files = new arraylist<file>();  
    if (!isroot) {
      files.add(folder.getparentfile()); 
    }
    file[] filterfiles = folder.listfiles(); 
    mitemcount.settext(filterfiles.length + "项"); 
    if (null != filterfiles && filterfiles.length > 0) {
      for (file file : filterfiles) {
        files.add(file);
      }
    }
    mfileadpter = new filelistadapter(this, files, isroot); 
    mlistview.setadapter(mfileadpter);
  }
  
  private class filelistadapter extends baseadapter {

    private context context;
    private arraylist<file> files;
    private boolean isroot;
    private layoutinflater minflater;
    
    public filelistadapter (context context, arraylist<file> files, boolean isroot) {
      this.context = context;
      this.files = files;
      this.isroot = isroot;
      minflater = layoutinflater.from(context);
    }
    
    @override
    public int getcount () {
      return files.size();
    }

    @override
    public object getitem (int position) {
      return files.get(position);
    }

    @override
    public long getitemid (int position) {
      return position;
    }
    
    @override
    public view getview (int position, view convertview, viewgroup parent) {
      viewholder viewholder;
      if(convertview == null) {
        viewholder = new viewholder();
        convertview = minflater.inflate(r.layout.file_list_item, null);
        convertview.settag(viewholder);
        viewholder.title = (textview) convertview.findviewbyid(r.id.file_title);
        viewholder.type = (textview) convertview.findviewbyid(r.id.file_type);
        viewholder.data = (textview) convertview.findviewbyid(r.id.file_date);
        viewholder.size = (textview) convertview.findviewbyid(r.id.file_size);
      } else {
        viewholder = (viewholder) convertview.gettag();
      }
      
      file file = (file) getitem(position);
      if(position == 0 && !isroot) {
        viewholder.title.settext("返回上一级");
        viewholder.data.setvisibility(view.gone);
        viewholder.size.setvisibility(view.gone);
        viewholder.type.setvisibility(view.gone);
      } else {
        string filename = file.getname();
        viewholder.title.settext(filename);
        if(file.isdirectory()) {
          viewholder.size.settext("文件夹");
          viewholder.size.settextcolor(color.red);
          viewholder.type.setvisibility(view.gone);
          viewholder.data.setvisibility(view.gone);
        } else {
          long filesize = file.length();
          if(filesize > 1024*1024) {
            float size = filesize /(1024f*1024f);
            viewholder.size.settext(new decimalformat("#.00").format(size) + "mb");
          } else if(filesize >= 1024) {
            float size = filesize/1024;
            viewholder.size.settext(new decimalformat("#.00").format(size) + "kb");
          } else {
            viewholder.size.settext(filesize + "b");
          }
          int dot = filename.indexof('.');
          if(dot > -1 && dot < (filename.length() -1)) {
            viewholder.type.settext(filename.substring(dot + 1) + "文件");
          }
          viewholder.data.settext(new simpledateformat("yyyy/mm/dd hh:mm").format(file.lastmodified()));
        }
      }
      return convertview;
    }
    
    class viewholder {
      private textview title;
      private textview type;
      private textview data;
      private textview size;
    }
  }

  @override
  public void onitemclick (adapterview<?> parent, view view, int position, long id) {
    file file = (file) mfileadpter.getitem(position);
    if(!file.canread()) {
      new alertdialog.builder(this).settitle("提示").setmessage("权限不足").setpositivebutton(android.r.string.ok, new onclicklistener() {
        
        @override
        public void onclick (dialoginterface dialog, int which) {
          
        }
      }).show();
    } else if(file.isdirectory()) {
      initdata(file);
    } else {
      openfile(file);
    }
  }
  
  private void openfile(file file) {
    intent intent = new intent();
    intent.addflags(intent.flag_activity_new_task); 
    intent.setaction(intent.action_view); 
    string type = getmimetype(file); 
    intent.setdataandtype(uri.fromfile(file), type); 
    try {
      startactivity(intent);
    }
    catch (exception e) {
      toast.maketext(this, "未知类型,不能打开", toast.length_short).show();
    }
  }
  
  private string getmimetype(file file) {
    string type = "*/*";
    string filename = file.getname();
    int dotindex = filename.indexof('.');
    if(dotindex < 0) {
      return type;
    }
    string end = filename.substring(dotindex, filename.length()).tolowercase();
    if(end == "") {
      return type;
    }
    for(int i=0; i<mime_maptable.length; i++) {
      if(end == mime_maptable[i][0]) {
        type = mime_maptable[i][1] ;
      }
    }
    return type;
  }
  
  private final string[][] mime_maptable = {
    // {后缀名, mime类型}
    { ".3gp", "video/3gpp" }, 
    { ".apk", "application/vnd.android.package-archive" }, 
    { ".asf", "video/x-ms-asf" }, 
    { ".avi", "video/x-msvideo" },
    { ".bin", "application/octet-stream" }, 
    { ".bmp", "image/bmp" }, 
    { ".c", "text/plain" }, 
    { ".class", "application/octet-stream" },
    { ".conf", "text/plain" }, 
    { ".cpp", "text/plain" }, 
    { ".doc", "application/msword" },
    { ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, 
    { ".xls", "application/vnd.ms-excel" },
    { ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, 
    { ".exe", "application/octet-stream" },
    { ".gif", "image/gif" }, 
    { ".gtar", "application/x-gtar" }, 
    { ".gz", "application/x-gzip" }, 
    { ".h", "text/plain" }, 
    { ".htm", "text/html" },
    { ".html", "text/html" }, 
    { ".jar", "application/java-archive" }, 
    { ".java", "text/plain" }, 
    { ".jpeg", "image/jpeg" },
    { ".jpg", "image/jpeg" }, 
    { ".js", "application/x-javascript" }, 
    { ".log", "text/plain" }, 
    { ".m3u", "audio/x-mpegurl" },
    { ".m4a", "audio/mp4a-latm" }, 
    { ".m4b", "audio/mp4a-latm" }, 
    { ".m4p", "audio/mp4a-latm" }, 
    { ".m4u", "video/vnd.mpegurl" },
    { ".m4v", "video/x-m4v" }, 
    { ".mov", "video/quicktime" }, 
    { ".mp2", "audio/x-mpeg" }, 
    { ".mp3", "audio/x-mpeg" }, 
    { ".mp4", "video/mp4" },
    { ".mpc", "application/vnd.mpohun.certificate" }, 
    { ".mpe", "video/mpeg" }, 
    { ".mpeg", "video/mpeg" }, 
    { ".mpg", "video/mpeg" },
    { ".mpg4", "video/mp4" }, 
    { ".mpga", "audio/mpeg" }, 
    { ".msg", "application/vnd.ms-outlook" }, 
    { ".ogg", "audio/ogg" },
    { ".pdf", "application/pdf" }, 
    { ".png", "image/png" }, 
    { ".pps", "application/vnd.ms-powerpoint" },
    { ".ppt", "application/vnd.ms-powerpoint" }, 
    { ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
    { ".prop", "text/plain" }, 
    { ".rc", "text/plain" }, 
    { ".rmvb", "audio/x-pn-realaudio" }, 
    { ".rtf", "application/rtf" },
    { ".sh", "text/plain" }, 
    { ".tar", "application/x-tar" }, 
    { ".tgz", "application/x-compressed" }, 
    { ".txt", "text/plain" },
    { ".wav", "audio/x-wav" }, 
    { ".wma", "audio/x-ms-wma" }, 
    { ".wmv", "audio/x-ms-wmv" }, 
    { ".wps", "application/vnd.ms-works" },
    { ".xml", "text/plain" }, 
    { ".z", "application/x-compress" }, 
    { ".zip", "application/x-zip-compressed" }, 
    { "", "*/*" } 
    };
}

最后补充一下,布局文件中的dimension是编译到jar包里面去了的,没有jar包的童鞋可以改成自己定义大小。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。