文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动的保存到文件当中的。

概述

文件存取的核心就是输入流和输出流。

Android文件的操作模式

文件的相关操作方法

文件读写的实现

openFileOutput和openFileInput方法

/**

* openFIleOutput ,openFileInput

* 这两种方法同sp一样只能讲文件保存到手机内存固定的路径中,

* 默认为 /data/data//files

*/

private void save2File() {

try {

//向文件写入内容

FileOutputStream os = openFileOutput("file.txt", Context.MODE_PRIVATE);

String text = "写数据到文件";

os.write(text.getBytes("utf-8"));

//关闭流

os.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

*

*/

private void readFile() {

try {

FileInputStream ins = openFileInput("file.txt");

byte[] buffer = new byte[100];

int byteCount = ins.read(buffer);

String text = new String(buffer,0,byteCount,"utf-8");

Toast.makeText(this,text,Toast.LENGTH_SHORT).show();

ins.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

文件存储位置

/data/data//files目录下

openFileOutput和openFileInput方法可以获得操作文件的OutputStream以及InputStream对象,而且可以通过流对象处理任何文件的数据,但是这两个方法同SharedPreferences一样,只能在手机内存卡的指定目录建立文件,因此在使用上仍然有一定的局限性。

读取SD卡上的文件

main_activity.xml:

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/LinearLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.jay.example.filedemo2.MainActivity">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="清输入文件名" />

android:id="@+id/edittitle"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="文件名" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="清输入文件内容" />

android:id="@+id/editdetail"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="文件内容" />

android:id="@+id/btnsave"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="保存到SD卡" />

android:id="@+id/btnclean"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="清空" />

android:id="@+id/btnread"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="读取sd卡中的文件" />

接着我们来写一个SD操作类: SDFileHelper.Java

public class SDFileHelper {

private Context context;

public SDFileHelper() {

}

public SDFileHelper(Context context) {

super();

this.context = context;

}

//往SD卡写入文件的方法

public void savaFileToSD(String filename, String filecontent) throws Exception {

//如果手机已插入sd卡,且app具有读写sd卡的权限

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

filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;

//这里就不要用openFileOutput了,那个是往手机内存中写数据的

FileOutputStream output = new FileOutputStream(filename);

output.write(filecontent.getBytes());

//将String字符串以字节流的形式写入到输出流中

output.close();

//关闭输出流

} else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();

}

//读取SD卡中文件的方法

//定义读取文件的方法:

public String readFromSD(String filename) throws IOException {

StringBuilder sb = new StringBuilder("");

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

filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;

//打开文件输入流

FileInputStream input = new FileInputStream(filename);

byte[] temp = new byte[1024];

int len = 0;

//读取文件内容:

while ((len = input.read(temp)) > 0) {

sb.append(new String(temp, 0, len));

}

//关闭输入流

input.close();

}

return sb.toString();

}

}

接着MainActivity.java实现相关逻辑:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

private EditText editname;

private EditText editdetail;

private Button btnsave;

private Button btnclean;

private Button btnread;

private Context mContext;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mContext = getApplicationContext();

bindViews();

}

private void bindViews() {

editname = (EditText) findViewById(R.id.edittitle);

editdetail = (EditText) findViewById(R.id.editdetail);

btnsave = (Button) findViewById(R.id.btnsave);

btnclean = (Button) findViewById(R.id.btnclean);

btnread = (Button) findViewById(R.id.btnread);

btnsave.setOnClickListener(this);

btnclean.setOnClickListener(this);

btnread.setOnClickListener(this);

}

@Override

public void onClick(View v) {

switch (v.getId()){

case R.id.btnclean:

editdetail.setText("");

editname.setText("");

break;

case R.id.btnsave:

String filename = editname.getText().toString();

String filedetail = editdetail.getText().toString();

SDFileHelper sdHelper = new SDFileHelper(mContext);

try

{

sdHelper.savaFileToSD(filename, filedetail);

Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();

}

catch(Exception e){

e.printStackTrace();

Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();

}

break;

case R.id.btnread:

String detail = "";

SDFileHelper sdHelper2 = new SDFileHelper(mContext);

try

{

String filename2 = editname.getText().toString();

detail = sdHelper2.readFromSD(filename2);

}

catch(IOException e){e.printStackTrace();}

Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();

break;

}

}

}

最后别忘记在AndroidManifest.xml写上读写SD卡的权限哦!

如何判断虚拟和物理两种SDK

在默认情况下,会将一部分存储空间分给虚拟的SD卡使用(一部分用于安装Android操作系统)

android.os.Enviroment.isExternalStorageRemovalbe()

返回true:SD卡是物理的,反之SD卡是虚拟的。

用于适配不同型号手机,反射获取SD卡路径和状态

package com.turing.base.activity.dataStore.fileStore;

import android.content.Context;

import android.os.Environment;

import android.os.StatFs;

import android.os.storage.StorageManager;

import android.text.TextUtils;

import android.util.Log;

import java.io.File;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

* 用于适配不同型号手机,反射获取SD卡路径和状态

*

*/

public class DevMountInfo {

private final String TAG = DevMountInfo.class.getSimpleName();

private static final int ERROR = -1;

// class name

private final static String CLASS_NAME = "android.os.storage.StorageVolume";

//remained spare memory size

private static final int REMAINED_SPARE_IN_MB = 100;

// method name

private final static String METHOD_GET_VOLUME_LIST = "getVolumeList";

private final static String METHOD_GET_VOLUME_STATE = "getVolumeState";

private final static String METHOD_IS_REMOVABLE = "isRemovable";

private final static String METHOD_GET_PATH = "getPath";

private final static String MOUNTED = "mounted";

private static DevMountInfo INSTANCE;

private String mSDCardPath = null;

// internal file path

private ConcurrentLinkedQueue mInternalPathList = new ConcurrentLinkedQueue();

// external file path

private ConcurrentLinkedQueue mExternalPathList = new ConcurrentLinkedQueue();

private ExecutorService mExecutor = null;

private DevMountInfo() {

mExecutor = Executors.newSingleThreadExecutor();

}

public static DevMountInfo getInstance() {

synchronized (DevMountInfo.class) {

if (null == INSTANCE) {

INSTANCE = new DevMountInfo();

}

return INSTANCE;

}

}

@Override

protected void finalize() throws Throwable {

super.finalize();

synchronized (DevMountInfo.class) {

mInternalPathList.clear();

mExternalPathList.clear();

mExecutor.shutdown();

INSTANCE = null;

}

}

public void init(final Context context) {

mExecutor.execute(new Runnable() {

@Override

public void run() {

executeInit(context);

}

});

}

public boolean isSDCardFull() {

return REMAINED_SPARE_IN_MB > (getSDCardAvailSpace() * 1024);

}

public boolean isSDCardAvaiable() {

return !mExternalPathList.isEmpty() || !mInternalPathList.isEmpty();

}

public String getSDCardPath() {

return mSDCardPath;

}

public long getSDCardTotalSpace() {

long totalSpace = 0;

if (!TextUtils.isEmpty(mSDCardPath)) {

StatFs sf = new StatFs(mSDCardPath);

long blockSize = sf.getBlockSize();

long total = sf.getBlockCount();

totalSpace = total * blockSize / 1024;

}

return totalSpace;

}

public long getSDCardAvailSpace() {

long availSpace = 0;

if (!TextUtils.isEmpty(mSDCardPath)) {

StatFs sf = new StatFs(mSDCardPath);

long blockSize = sf.getBlockSize();

long availCount = sf.getAvailableBlocks();

availSpace = availCount * blockSize / 1024;

}

return availSpace;

}

public String getInternalSDCardPath() {

return mInternalPathList.peek();

}

public String getExternalSDCardPath() {

return mExternalPathList.peek();

}

private void executeInit(Context context) {

StorageManager mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

if (mStorageManager != null) {

Class> mStorageVolume = null;

Method mGetVolumeListMethod = null;

Method mGetVolumeStateMethod = null;

Method mGetPathMethod = null;

Method mIsRemovableMethod = null;

Object[] mStorageVolumeList = null;

try {

mStorageVolume = Class.forName(CLASS_NAME);

mGetVolumeListMethod = mStorageManager.getClass().getMethod(METHOD_GET_VOLUME_LIST, new Class[0]);

mGetVolumeStateMethod = mStorageManager.getClass().getMethod(METHOD_GET_VOLUME_STATE, new Class[]{String.class});

mIsRemovableMethod = mStorageVolume.getMethod(METHOD_IS_REMOVABLE, new Class[0]);

mGetPathMethod = mStorageVolume.getMethod(METHOD_GET_PATH, new Class[0]);

mStorageVolumeList = (Object[]) mGetVolumeListMethod.invoke(mStorageManager, new Object[0]);

boolean mIsRemovable = false;

if (mStorageVolumeList != null && mStorageVolumeList.length > 0) {

int mStorageVolumeCount = mStorageVolumeList.length;

Log.i(TAG, "init() === > StorageVolume Count = " + mStorageVolumeCount);

mInternalPathList.clear();

mExternalPathList.clear();

for (int i = 0; i < mStorageVolumeCount; ++i) {

String mStoragePath = (String) mGetPathMethod.invoke(mStorageVolumeList[i], new Object[0]);

mIsRemovable = ((Boolean) mIsRemovableMethod.invoke(mStorageVolumeList[i], new Object[0])).booleanValue();

if (!TextUtils.isEmpty(mStoragePath)) {

String state = (String) mGetVolumeStateMethod.invoke(mStorageManager, new Object[]{mStoragePath});

if ((state != null) && (state.equals(MOUNTED))) {

if (mIsRemovable) {

Log.i(TAG, "init() === > external storage path = (" + mStoragePath + ")");

mExternalPathList.add(mStoragePath);

} else {

Log.i(TAG, "init() === > internal storage path = (" + mStoragePath + ")");

mInternalPathList.add(mStoragePath);

}

}

}

}

}

} catch (ClassNotFoundException e) {

handleInvalid();

Log.e(TAG, "init() === > Exception:ClassNotFoundException");

} catch (NoSuchMethodException e) {

handleInvalid();

Log.e(TAG, "init() === > Exception:NoSuchMethodException");

} catch (IllegalArgumentException e) {

handleInvalid();

Log.e(TAG, "init() === > Exception:IllegalArgumentException");

} catch (IllegalAccessException e) {

handleInvalid();

Log.e(TAG, "init() === > Exception:IllegalAccessException");

} catch (InvocationTargetException e) {

handleInvalid();

Log.e(TAG, "init() === > Exception:InvocationTargetException");

}

} else {

handleInvalid();

Log.e(TAG, "init() === > can't get storage manager");

}

initSDCardPath();

}

private void handleInvalid() {

mInternalPathList.add(Environment.getExternalStorageDirectory().getPath());

}

private void initSDCardPath() {

if (!mExternalPathList.isEmpty()) {

mSDCardPath = mExternalPathList.peek();

} else if (!mInternalPathList.isEmpty()) {

mSDCardPath = mInternalPathList.peek();

} else {

mSDCardPath = Environment.getExternalStorageDirectory().getPath();

}

Log.i(TAG, "initSDCardPath() === > SDCARD PATH = (" + mSDCardPath + ")");

}

/**

* SDCARD是否存

*/

public static boolean externalMemoryAvailable() {

return android.os.Environment.getExternalStorageState().equals(

android.os.Environment.MEDIA_MOUNTED);

}

/**

* 获取手机内部剩余存储空间

*

* @return

*/

public static long getAvailableInternalMemorySize() {

File path = Environment.getDataDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long availableBlocks = stat.getAvailableBlocks();

return availableBlocks * blockSize;

}

/**

* 获取手机内部总的存储空间

*

* @return

*/

public static long getTotalInternalMemorySize() {

File path = Environment.getDataDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long totalBlocks = stat.getBlockCount();

return totalBlocks * blockSize;

}

/**

* 获取手机内置存储剩余存储空间

*

* @return

*/

public static long getAvailableInternalSystemMemorySize() {

File path = Environment.getRootDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long availableBlocks = stat.getAvailableBlocks();

return availableBlocks * blockSize;

}

/**

* 获取手机内置存储总的存储空间

*

* @return

*/

public static long getTotalInternalSystemMemorySize() {

File path = Environment.getRootDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long totalBlocks = stat.getBlockCount();

return totalBlocks * blockSize;

}

/**

* 获取SDCARD剩余存储空间

*

* @return

*/

public static long getAvailableExternalMemorySize() {

if (externalMemoryAvailable()) {

File path = Environment.getExternalStorageDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long availableBlocks = stat.getAvailableBlocks();

return availableBlocks * blockSize;

} else {

return ERROR;

}

}

/**

* 获取SDCARD总的存储空间

*

* @return

*/

public static long getTotalExternalMemorySize() {

if (externalMemoryAvailable()) {

File path = Environment.getExternalStorageDirectory();

StatFs stat = new StatFs(path.getPath());

long blockSize = stat.getBlockSize();

long totalBlocks = stat.getBlockCount();

return totalBlocks * blockSize;

} else {

return ERROR;

}

}

public static long getAvailableMemorySize(String path) {

if (null == path)

return 0;

StatFs stat = new StatFs(path);

long blockSize = stat.getBlockSize();

long availableBlocks = stat.getAvailableBlocks();

return availableBlocks * blockSize;

}

}

读取raw和assets文件夹下的文件

相信大家对两个文件夹并不陌生,如果我们不想自己的文件被编译成二进制文件的话, 我们可以把文件放到这两个目录下,而两者的区别如下:

res/raw:文件会被映射到R.java文件中,访问的时候直接通过资源ID即可访问,而且 他不能有目录结构,就是不能再创建文件夹

assets:不会映射到R.java文件中,通过AssetManager来访问,能有目录结构,即, 可以自行创建文件夹。

读取文件资源:

res/raw:

InputStream is =getResources().openRawResource(R.raw.filename);

assets:

AssetManager am = getAssets();

InputStream is = am.open("filename");

SAX引擎读取XML文件

sax引擎读取xml文件的原理:

sax技术在处理xml文件时并不一次性把xml文件装入内存,而是一边读一般解析。

使用sax处理xml需要一个Handler对象,一般会使用org.xml.sax.helpers.DefaultHandler的子类作为Handler对象

因此,这就需要处理如下5个分析点,也可称为分析事件:

开始分析xml文件。该分析点表示sax引擎刚开始处理xml文件,还没有读取xml文件中的内容。该分析点对应于DefaultHandler类中的startDocument()事件方法,可以在该方法中做一下初始化的工作!

开始处理每一个xml元素,也就是遇到,这样的起始标记,sax引擎每次扫描到新的xml元素的起始标记会触发这个分析事件,对应的事件分析方法是startElement,在该方法中可以获取当前元素的名称和元素属性的相关信息

处理完一个xml元素,也就是遇到,这样的结束标记,该分析点对应的事件方法是endElement,在该事件中可以获得当前处理完的元素的全部信息。

处理完xml文件。如果sax引擎将整个xml文件的内容都扫描完了,就到了这个分析点,该分析点对应的事件方法endDocument(),该事件方法可能不是必需的,如果最后有以下收尾工作,如释放一下资源,可以在该方法中完成!

读取字符分析点。这是最重要的分析点。如果没有这个分析点,前4步的处理相当于白跑一遍,虽然读取了xml文件中的所有内容,但并未保存这些内容,而这个分析点所对应的characters事件方法的主要作用就是保存sax引擎读取的xml文件中的内容。更准确地说是保存xml元素的文本,也就是abc中的abc。

Code

res\raw\product.xml

10

电脑

2067.25

20

微波炉

520

30

洗衣机

2400

Product.java

public class Product

{

private int id;

private String name;

private float price;

public int getId()

{

return id;

}

public void setId(int id)

{

this.id = id;

}

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

public float getPrice()

{

return price;

}

public void setPrice(float price)

{

this.price = price;

}

}

XML2Product.java(DefaultHandler子类)

DefaultHandler子类 ,核心类,负责处理分析点事件。

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;

import java.util.List;

public class XML2Product extends DefaultHandler {

private List products;

private Product product;

private StringBuffer buffer = new StringBuffer();

public List getProducts() {

return products;

}

@Override

public void characters(char[] ch, int start, int length)

throws SAXException {

buffer.append(ch, start, length);

super.characters(ch, start, length);

}

@Override

public void startDocument() throws SAXException {

// 开始分析xml文件,创建List对象用于保存分析完的Product对象

products = new ArrayList();

}

@Override

public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException {

if (localName.equals("product")) {

// 如果分析的是标签,则创建一个Product对象

product = new Product();

}

super.startElement(uri, localName, qName, attributes);

}

@Override

public void endElement(String uri, String localName, String qName)

throws SAXException {

if (localName.equals("product")) {

// 处理完 标签后 将product对象添加到products中

products.add(product);

} else if (localName.equals("id")) {

// 设置id属性的值

product.setId(Integer.parseInt(buffer.toString().trim()));

// 将标签内容的缓存区清空

buffer.setLength(0);

} else if (localName.equals("name")) {

product.setName(buffer.toString().trim());

buffer.setLength(0);

} else if (localName.equals("price")) {

product.setPrice(Float.parseFloat(buffer.toString().trim()));

buffer.setLength(0);

}

super.endElement(uri, localName, qName);

}

}

Xml2JavaObjectAct

import android.app.AlertDialog;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.util.Xml;

import android.view.View;

import com.turing.base.R;

import java.io.InputStream;

import java.util.List;

public class Xml2JavaObjectAct extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_xml2_java_object);

}

public void onClick_XMLToObject(View view) {

try {

// 打开资源文件

InputStream is = getResources().openRawResource(R.raw.products);

XML2Product xml2Product = new XML2Product();

// 开始分析priducts.xml文件

android.util.Xml.parse(is, Xml.Encoding.UTF_8, xml2Product);

// 输出转换后的java对象

List products = xml2Product.getProducts();

String msg = "共" + products.size() + "个产品\n";

for (Product product : products) {

msg += "id:" + product.getId() + " 产品名:" + product.getName()

+ " 价格:" + product.getPrice() + "\n";

}

// 弹出对话框

new AlertDialog.Builder(this).setTitle("产品信息").setMessage(msg)

.setPositiveButton("关闭", null).show();

} catch (Exception e) {

}

}

}

效果图

Code

activity_jar_zip.xml

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:onClick="onClick_Jar_Compress"

android:text="用jar格式压缩文件" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:onClick="onClick_Jar_Uncompress"

android:text="解压jar格式文件" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:onClick="onClick_Zip_Compress"

android:text="用zip格式压缩文件" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:onClick="onClick_Zip_Uncompress"

android:text="解压zip格式文件" />

JarZipAct

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Toast;

import com.turing.base.R;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.util.jar.JarEntry;

import java.util.jar.JarInputStream;

import java.util.jar.JarOutputStream;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;

import java.util.zip.ZipOutputStream;

public class JarZipAct extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_jar_zip);

}

public void onClick_Jar_Compress(View view) {

try {

// 使用FileOutputStream对象指定一个要输出的压缩文件(file.jar)

FileOutputStream fos = new FileOutputStream(

android.os.Environment.getExternalStorageDirectory()

+ "/file.jar");

// 第一步 创建JarOutputStream对象

JarOutputStream jos = new JarOutputStream(fos);

// 第二步 创建一个JarEntry对象,并指定待压缩文件在压缩包中的文件名

JarEntry jarEntry = new JarEntry("strings.xml");

jos.putNextEntry(jarEntry);

InputStream is = getResources().getAssets().open("strings.xml");

byte[] buffer = new byte[8192];

int count = 0;

// 第四步 写入数据

while ((count = is.read(buffer)) >= 0) {

jos.write(buffer, 0, count);

}

// 第五步 关闭当前的JarEntry等对象

is.close();

jos.closeEntry();

jos.close();

Toast.makeText(this, "成功将strings.xml文件以jar格式压缩.", Toast.LENGTH_LONG)

.show();

} catch (Exception e) {

Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();

}

}

public void onClick_Jar_Uncompress(View view) {

try {

// 定义要解压的文件

String filename = android.os.Environment

.getExternalStorageDirectory() + "/file.jar";

if (!new File(filename).exists()) {

Toast.makeText(this, "压缩文件不存在.", Toast.LENGTH_LONG).show();

return;

}

// 使用FileInputStream对象指定要解压的对象

FileInputStream fis = new FileInputStream(filename);

// 1 创建JarInputStream对象来读取压缩文件(file.jar)

JarInputStream jis = new JarInputStream(fis);

// 2 调用getNextJarEntry方法打开压缩包中的第一个文件 ,如果有多个,多次调用该方法

JarEntry jarEntry = jis.getNextJarEntry();

// 3 输出已解压的文件

FileOutputStream fos = new FileOutputStream(

android.os.Environment.getExternalStorageDirectory()

+ "/" + jarEntry.getName());

byte[] buffer = new byte[8192];

int count = 0;

// 4 输出已解压的字节流

while ((count = jis.read(buffer)) >= 0) {

fos.write(buffer, 0, count);

}

// 5 关闭

jis.closeEntry();

jis.close();

fos.close();

Toast.makeText(this, "成功解压jar格式的文件.", Toast.LENGTH_LONG).show();

} catch (Exception e) {

Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();

}

}

public void onClick_Zip_Compress(View view) {

try {

// 指定了2个待压缩的w文件,都在assets目录中

String[] filenames = new String[]

{"main.xml", "strings.xml"};

FileOutputStream fos = new FileOutputStream(

android.os.Environment.getExternalStorageDirectory()

+ "/file.zip");

ZipOutputStream zos = new ZipOutputStream(fos);

int i = 1;

//枚举filenames中的所有待压缩文件

while (i <= filenames.length) {

// 从filenames数组中取出当前待压缩的温佳明,作为压缩后的文件名,以保持要说前后文件名称一致

ZipEntry zipEntry = new ZipEntry(filenames[i - 1]);

// 打开当前的ZipEntry对象

zos.putNextEntry(zipEntry);

InputStream is = getResources().getAssets().open(

filenames[i - 1]);

byte[] buffer = new byte[8192];

int count = 0;

// 写入数据

while ((count = is.read(buffer)) >= 0) {

zos.write(buffer, 0, count);

}

zos.flush();

// 关闭当前的ZipEntry对象

zos.closeEntry();

is.close();

i++;

}

zos.finish();

zos.close();

Toast.makeText(this, "成功将main.xml、strings.xml文件以zip格式压缩.",

Toast.LENGTH_LONG).show();

} catch (Exception e) {

Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();

}

}

public void onClick_Zip_Uncompress(View view) {

try {

// 指定待解压的文件

String filename = android.os.Environment

.getExternalStorageDirectory() + "/file.zip";

if (!new File(filename).exists()) {

Toast.makeText(this, "压缩文件不存在.", Toast.LENGTH_LONG).show();

return;

}

FileInputStream fis = new FileInputStream(filename);

ZipInputStream zis = new ZipInputStream(fis);

ZipEntry zipEntry = null;

// 通过不断调用getNextEntry方法来解压file.zip中所有的文件

while ((zipEntry = zis.getNextEntry()) != null) {

FileOutputStream fos = new FileOutputStream(

android.os.Environment.getExternalStorageDirectory()

+ "/" + zipEntry.getName());

byte[] buffer = new byte[8192];

int count = 0;

while ((count = zis.read(buffer)) >= 0) {

fos.write(buffer, 0, count);

}

zis.closeEntry();

fos.close();

}

zis.close();

Toast.makeText(this, "成功解压jar格式的文件.", Toast.LENGTH_LONG).show();

} catch (Exception e) {

Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();

}

}

}

原文链接:http://blog.csdn.net/yangshangwei/article/details/50831269

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

android字节流保存,android数据存储之文件存储方法相关推荐

  1. Android 保存QQ密码(数据存储:文件存储、SharedPreferences)

    源码[工程文件]:https://gitee.com/lwx001/saveQQ MainActivity.java: package cn.lwx.saveqq;import android.os. ...

  2. Android(数据存储:文件存储、SharedPreferences)验证QQ密码

    前情提要1 :静态页面-简易QQ登录页面(纯activity_main.xml页面) [https://blog.csdn.net/weixin_44949135/article/details/10 ...

  3. Android数据存储、文件存储、SQLite数据库简单使用、 sharedPreferences存储(五)

    文章目录 5 数据存储 5.1 数据的存储方式 5.2 文件存储 5.2.1 将数据存入文件中 5.2.2 从文件中读取数据 5.2.3 实战演练-保存QQ账号和密码(内部存储) 5.2.4 实战演练 ...

  4. Android基础知识(二十一):Android五大存储之文件存储、Content Provider存储和网络存储

    Android基础知识(二十一):Android五大存储之文件存储.Content Provider存储和网络存储 一.Android存储--持久化技术 数据持久化是指将那些内存中的瞬时数据保存到存储 ...

  5. android SharedPreferences保存list数据

    今天,简单讲讲如何使用  SharedPreferences保存list数据. 网上找了很多资料,还是觉得这种比较简单.直接上代码: 保存: public static boolean saveA ...

  6. android 同步list数据,android SharedPreferences保存list数据

    释放双眼,带上耳机,听听看~! 今天,简单讲讲如何使用SharedPreferences保存list数据. 网上找了很多资料,还是觉得这种比较简单.直接上代码: 保存: public static b ...

  7. python保存数据到本地文件_python保存数据到本地文件的方法

    python保存数据到本地文件的方法 1.保存列表为.txt文件 #1/list写入txt ipTable = ['158.59.194.213', '18.9.14.13', '58.59.14.2 ...

  8. android运行时状态,Android 如何保存Android 运行时状态

    Android 如何保存Android 运行时状态 使用 SaveInstanceState去保存运行时数据 首先,我们需要重写一下系统的public void onSaveInstanceState ...

  9. 对象存储2:数据存储类型-文件存储、块存储、对象存储详解

    上一篇介绍了传统存储的几个常用类型,本篇主要介绍云平台用到的常用存储类型,分别是文件存储.块存储和对象存储. 这种分类是以数据存储的方式来命名的,体现了不同的数据存储格式.文件存储会以文件和文件夹的层 ...

  10. python读取数据库数据、并保存为docx_Python从数据库读取大量数据批量写入文件的方法...

    Python从数据库读取大量数据批量写入文件的方法 使用机器学习训练数据时,如果数据量较大可能我们不能够一次性将数据加载进内存,这时我们需要将数据进行预处理,分批次加载进内存. 下面是代码作用是将数据 ...

最新文章

  1. ISP 【一】————boost标准库使用——批量读取保存文件 /boost第三方库的使用及其cmake添加,图像gramma
  2. 【Paper】2017_水下潜航器编队海洋勘测的协调控制方法研究
  3. 从证书中导出公钥并存放到项目中
  4. 生产环境中on yarn模式是否采用yarn session
  5. Java面向对象(2)--类的成员属性
  6. 阿里云 Aliplayer高级功能介绍(九):自动播放体验
  7. java 拆箱 类型不对,Java基本类型于对象类型的拆箱和装箱
  8. python中函数的意义_3分钟搞懂Python中dict函数的含义是什么
  9. 最全jar包下载链接
  10. 解决软件开发中常见的问题
  11. Python制作某电商平台商品竞拍脚本,能自动定时、抢拍、购买
  12. 微信机器人 DIY 从 0 到 1
  13. java 获取文件后缀及根据文件扩展名判断文件是否图片格式
  14. tp6 隐藏身份证号中间8位
  15. 团队博客-第二周:需求规格说明书(科利尔拉弗队)
  16. 10019---CSS Grouping Selectors(分组和嵌套)
  17. 【Python自学笔记】报错No module Named Wandb
  18. java 如何定时_Java怎么实现定时提醒功能
  19. 汶川大地震随感谢摘录
  20. 翻译: Github Copilot 可以创作艺术吗?

热门文章

  1. [雪峰磁针石博客]接口测试面试题
  2. NLP - snownlp
  3. ubuntu16安装Times New Roma字体 / WPS 安装Times New Roma字体
  4. si4438使用stm32f103配置调试成功!
  5. 新手零基础一小时学会小程序开发制作教程
  6. FineBI 项目资源迁移
  7. 从零开始的腾讯电脑管家下载安装配置教程
  8. delphi10.1调用BarTender2016R5文件打印标签
  9. C#获得汉字对应区位码
  10. 威纶通触摸屏232脚位_威纶触摸屏tk6070iq232接口引脚电 – 手机爱问