(一)、引入:Android中提供了特有的两个方法来进行IO操作(openFileInput()和openFileOutput() ),但是毕竟手机内置存储空间很有限,为了更好地存储应用程序的大文件数据,需要读写SD卡上的文件。SD卡大大扩充了手机的存储能力。
(二)、读写SD卡的步骤:
1、先判断手机是否有sd卡;
调用Environment的getExternalStorageState()方法判断手机是否插上sdcard。
2、获取sdcard的路径;
调用Environment的getExternalStorageDirectory()方法来获取外部存储器的目录。
3、此外还可以获取SDCard可用磁盘空间的大小(借助StatFs类来实现);
4、清单文件中设置读写sdcard的权限;
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 在sdcard中创建与删除文件的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 向sdcard写入权限
5、执行读写操作(基本IO流操作)。
(三)、封装SDCard的工具类:SDCardHelper类
public class SDCardHelper {
private static String TAG = "SDCardHelper";
/*
* 判断sdcard是否挂载
*/
public static boolean isSDCardMounted() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
* 获取sdcard绝对物理路径
*/
public static String getSDCardPath() {
if (isSDCardMounted()) {
return Environment.getExternalStorageDirectory().getAbsolutePath();
} else {
return null;
}
* 获取sdcard的全部的空间大小。返回MB字节
*/
public static long getSDCardSize() {
if (isSDCardMounted()) {
StatFs fs = new StatFs(getSDCardPath());
long size = fs.getBlockSize();
long count = fs.getBlockCount();
return size * count / 1024 / 1024;
}
return 0;
* 获取sdcard的剩余的可用空间的大小。返回MB字节
*/
public static long getSDCardFreeSize() {
if (isSDCardMounted()) {
StatFs fs = new StatFs(getSDCardPath());
long size = fs.getBlockSize();
long count = fs.getAvailableBlocks();
return size * count / 1024 / 1024;
}
return 0;
* 将文件(byte[])保存进sdcard指定的路径下
*/
public static boolean saveFileToSDCard(byte[] data, String dir,
String filename) {
BufferedOutputStream bos = null;
if (isSDCardMounted()) {
Log.i(TAG, "==isSDCardMounted==TRUE");
File file = new File(getSDCardPath() + File.separator + dir);
Log.i(TAG, "==file:" + file.toString() + file.exists());
if (!file.exists()) {
boolean flags = file.mkdirs();
Log.i(TAG, "==创建文件夹:" + flags);
}
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(
file, filename)));
bos.write(data, 0, data.length);
bos.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
* 已知文件的路径,从sdcard中获取到该文件,返回byte[]
*/
public static byte[] loadFileFromSDCard(String filepath) {
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
if (isSDCardMounted()) {
File file = new File(filepath);
if (file.exists()) {
try {
baos = new ByteArrayOutputStream();
bis = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[1024 * 8];
int c = 0;
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
baos.flush();
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
(四)、案例:
1、功能:点击按钮,实现从网络上访问图片,将图片保存进SDCard中。点击另外一按钮,可以获取到刚才保存进SDCard中的图片,将其加载的页面中的ImageView控件中。
2、示例代码:、示例代码:
public class MainActivity extends Activity {
private ImageView imageView_main_img;
private String urlString = "http://t2.baidu.com/it/u=2,1891512358&fm=19&gp=0.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView_main_img = (ImageView) findViewById(R.id.imageView_main_img);
public void clickButton(View view) {
switch (view.getId()) {
case R.id.button_main_save:
new MyTask(this).execute(urlString);
break;
case R.id.button_main_show:
String filepath = SDCardHelper.getSDCardPath() + File.separator
+ "mydir" + File.separator + "firstimg.jpg";
byte[] data = SDCardHelper.loadFileFromSDCard(filepath);
if (data != null) {
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
imageView_main_img.setImageBitmap(bm);
} else {
Toast.makeText(this, "没有该图片!", Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
class MyTask extends AsyncTask<String, Void, byte[]> {
private Context context;
private ProgressDialog pDialog;
public MyTask(Context context) {
this.context = context;
pDialog = new ProgressDialog(context);
pDialog.setIcon(R.drawable.ic_launcher);
pDialog.setMessage("图片加载中...");
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.show();
}
@Override
protected byte[] doInBackground(String... params) {
BufferedInputStream bis = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
URL url = new URL(params[0]);
HttpURLConnection httpConn = (HttpURLConnection) url
.openConnection();
httpConn.setDoInput(true);
httpConn.connect();
if (httpConn.getResponseCode() == 200) {
bis = new BufferedInputStream(httpConn.getInputStream());
byte[] buffer = new byte[1024 * 8];
int c = 0;
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(byte[] result) {
super.onPostExecute(result);
if (result == null) {
Toast.makeText(context, "图片加载失败!", Toast.LENGTH_LONG).show();
} else {
// 将字节数组转成Bitmap,然后将bitmap加载的imageview控件中
// Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0,
// result.length);
// imageView_main_img.setImageBitmap(bitmap);
if (SDCardHelper.saveFileToSDCard(result, "mydir",
"firstimg.jpg")) {
Toast.makeText(context, "图片保存OK!", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(context, "图片保存失败!", Toast.LENGTH_LONG)
.show();
}
}
pDialog.dismiss();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;