Android文件读写操作
一、文件的基本操作
Android中可以在设备本身的存储设备或外接的存储设备中创建用于保存数据的文件。在默认状态下,文件是不能在不同程序间共享的。
当用户卸载您的应用程序时,这些文件删除。
文件存储数据可以通过openFileOutput方法打开一个文件(如果这个)文件不存在就自动创建这个文件),通过load方法来获取文件中的
数据,通过deleteFile方法删除一个指定的文件。
1,常用方法介绍:
File是通过FileInputStream和FileOutputStream对文件进行操作。
Context提供了如下两个方法来打开本应用程序的数据文件将爱丽的文件IO流。
FileInputStream openFileInput(String name):
打开应用程序的数据文件夹下的name文件对应输入流。
FileOutputStream openFileOutput(String name,int mode):
打开应用程序的数据文件夹下的name文件对应输出流。
参数:mode 指定打开文件的模式,该模式支持如下值:
MODE_PRIVATE :该文件只能被当前程序读写。
MODE_APPEND:以追加方式打开该文件,应用程序可以向该文件中追加内容。
MODE_WORLD_READABLE:该文件的内容可以被其他应用程序读取。
MODE_WORLD_WRITEABLE:该文件的内容可由其他程序读、写。
getDir(String name,int mode):
在应用程序的数据文件夹下获取或创建name对应的子目录。
File getFilesDir():
获取该应用程序的数据文件夹的绝对路径。
String[] fileList():
返回该应用程序中的数据文件夹下的全部文件。
deleteFile(String):
删除该应用程序的数据文件夹下的指定文件。
2,文件的创建、删除、重命名
//创建文件的名称 public static final String FILE_NAME="myFile.txt";
(1)创建文件代码示例:
File file=new File(FileUtil.FILE_NAME); //文件是否存在 if(!file.exists()) { try { //文件不存在,就创建一个新文件 file.createNewFile(); System.out.println("文件已经创建了"); } catch (IOException e) { e.printStackTrace(); } } else { System.out.println("文件已经存在"); System.out.println("文件名:"+file.getName()); System.out.println("文件绝对路径为:"+file.getAbsolutePath()); //是存在工程目录下,所以 System.out.println("文件相对路径为:"+file.getPath()); System.out.println("文件大小为:"+file.length()+"字节"); System.out.println("文件是否可读:"+file.canRead()); System.out.println("文件是否可写:"+file.canWrite()); System.out.println("我呢间是否隐藏:"+file.isHidden()); }
(2)删除文件示例:
File file=new File(FileUtil.FILE_NAME); //文件是否存在 if(file.exists()) { file.delete(); System.out.println("文件已经被删除了"); }
(3)为文件重命名示例:
File file=new File(FileUtil.FILE_NAME); File newFile=new File("anotherFile.txt"); file.renameTo(newFile); System.out.println("文件已经成功地被命名了"+file.getName());
注意:当我们为文件重命名时,仅仅操作的是文件本身,内部的内容不会改变。
2,文件夹的创建和删除
//创建文件夹的名称 //public static final String FOLDER_NAME="NewFolder"; //多级目录,不能用/ /* * File.separator路径分隔符 * 在文件夹的目录结构中,只要任一级目录不存在,那么都会不存在。 * 比如"NewFolder2"+File.separator+"separator2"此路径,NewFolder2没有存在, * 所以NewFolder2和separator2都不存在 * */ public static final String FOLDER_NAME= "NewFolder"+File.separator+"separator";
(1)创建文件夹代码示例
File folder=new File(FileUtil.FOLDER_NAME); if(!folder.exists()) { //创建文件夹,一旦存在相同的文件或文件夹,是不可能存在的。 /* * * 在文件夹的目录结构中,只要任一级目录不存在,那么都会不存在。 * 比如"NewFolder2"+File.separator+"separator2"此路径,NewFolder2没有存在, * 所以NewFolder2和separator2都不存在 * */ // folder.mkdir(); /* * 不管路径是否存在,都会慢慢向下一级创建文件夹。 * 所以创建文件夹我们一般用此方法,确定稳定性。 * */ folder.mkdirs(); } File同时可以表示文件或文件夹
(2)删除文件夹
File folder=new File(FileUtil.FOLDER_NAME); if(folder.exists()) { /* * 在移除的时候,只会移除最下层的目录,不会移除多层目录。 * */ folder.delete(); }
二、读取Assets中的文件数据
在asset目录下的资源是无法直接访问的原生资源,但是这个目录保存的文件可以打包在程序里,Android应用通过Assetmanager来管理该目录下的原始资源.
Android不为Assets下的文件生成id,如要使用assets里的文件,需要指定文件的路径和文件名。
代码使用示例:
(1)在assets中创建文件:
info.txt
文件内容为:
1,这是使用UTF-8编写的一个文本
2,这是第二行代码
3,3行
4,4行
(2)activity_main.xml中的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF" tools:context="com.yuyan.android_file.MainActivity" > <Button android:id="@+id/readtxtBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="读取TXT数据" /> </RelativeLayout>
(3)MainActivity.java
private static final String TAG="ReadAssets"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.readtxtBtn).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //读取的内容会随着文件的改变而改变 try { //读取的是字节流 InputStream is=getResources().getAssets().open("info.txt"); //UTF-8编码的指定是很重要的 InputStreamReader isr=new InputStreamReader(is,"UTF-8"); BufferedReader bfr=new BufferedReader(isr); String in=""; while((in=bfr.readLine())!=null) { Log.i(TAG, in); } // Log.i(TAG, bfr.readLine()); } catch (IOException e) { e.printStackTrace(); } } }); }
三、读取raw目录中的文件数据
如果你想要将静态文件保存在您的应用程序在编译时,将文件保存在您的项目res/raw/目录。Android SDK会处理该目录下原始资源,并会在R清单类中为该目录下的资源生成一个索引项。
你可以打开它与openRawResource(),通过R.raw.<filename>的资源 id。此方法返回的InputStream,您可以使用读取该文件 (但你不能写入原始文件)。
(1)activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yuyan.android_raw.MainActivity" > <Button android:id="@+id/readrawBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="读取Raw文件夹中的数据" /> </RelativeLayout>
(2)MainActivity.java
private static final String TAG="RawData"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.readrawBtn).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { InputStream is=getResources().openRawResource(R.raw.info); InputStreamReader isr=new InputStreamReader(is,"UTF-8"); BufferedReader bfr=new BufferedReader(isr); String instring=""; while((instring=bfr.readLine())!=null) { Log.i(TAG, instring); } } catch (NotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); }
四、读写内部存储的文件数据
程序一旦在虚拟机或真机运行后,程序就会在固定地方创建一个文件夹。
应用程序的数据文件默认位置保存在:
/data/data/<package name>/files 目录下。 <package name>代表应用程序的包名。
一旦运行,就会在DDMs中创建一个内部的文件夹.比如运行一个包名为com.yuyan.android_internaldata的应用程序:
打开DDMS——>File Explorer——>data——>data——找到我们内部的工程——这个目录就是我们内部存储空间,对于其他应用是保密的。
就可以找到此应用程序的数据存储位置。
代码使用示例:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.yuyan.android_internaldata.MainActivity" > <EditText android:id="@+id/et" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="在这里输入内容" /> <Button android:id="@+id/writeBtn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="保存数据" /> <Button android:id="@+id/readBtn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="读取数据" /> <TextView android:id="@+id/show" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
MainActivity.java
et=(EditText) findViewById(R.id.et); show=(TextView) findViewById(R.id.show); findViewById(R.id.writeBtn).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { //将文件数据写到应用的内部存储 /* * 注意:获取流的方式通过openFileInput函数,指定文件名以及后缀 * 参数1.文件名和后缀 2.文件模式 * 保存在手机data/data/包名/files * */ FileOutputStream fos=openFileOutput(fileName, Context.MODE_PRIVATE); OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8"); osw.write(et.getText().toString()); //保证输出缓冲区中的所有内容 osw.flush(); fos.flush(); //后打开的先关闭,逐层向内关闭 fos.close(); osw.close(); Toast.makeText(MainActivity.this, "写入完成", Toast.LENGTH_LONG).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); findViewById(R.id.readBtn).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { FileInputStream fis=openFileInput(fileName); InputStreamReader is=new InputStreamReader(fis,"UTF-8"); //fis.available()文件可用长度 char input[]=new char[fis.available()]; is.read(input); is.close(); fis.close(); String readed=new String(input); show.setText(readed); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } });
五、读写外部存储的文件数据
1,认识
外部存储:每一个 Android 兼容设备支持共享的"外部存储器",你可以使用保存的文件。
这可以是一个可移动存储媒体 (如 SD 卡) 或内部的 (非可移动) 存储。保存
到外部存储的文件是可读的世界和他们启用 USB 大容量存储传输计算机上的文件
时,可以由用户修改。
谨慎 ︰
如果用户在计算机上安装外部存储或删除媒体,并没有强制执行时您将保存
到外部存储的文件的安全,外部存储可以变得不可用。所有应用程序都可以读取和
写入的文件放置在外部存储,用户可以删除它们。
SD卡数据存储路径;DDMS-->mnt-->sdcard(这里就是sd卡的挂载的位置)
其实真正的sdcard在storage的sdcard中——所对应的操作目录。
2,读、写SD卡上的文件如下步骤:
a,调用Environment的getExternalStorageState()方法判断手机上是否插入了SD卡,
并且应用程序具有读写SD卡的权限。例如使用如下代码:
//如果手机已插入SD卡,且应用程序具有读写SD卡的能力, //下面语句返回true Environment.getExternalStorageState().equals (Environment.MEDIA_MOUNTED)
b,调用Environment的getExternalStorageDirectory()方法来获取,外部存储器,也就是SD卡的目录.
c,调用FileInputStream、FileOutPutStream、FileReader或FileWriter读、写SD卡里的文件。
3,应用程序读、写SD卡的文件注意以下两点:
a,手机上应该已插入SD卡。
b,为了读、写SD卡上的数据,必须在应用程序的配置文件(AndroidManifest.xml)中添加读、写SD卡的权限,例如如下配置:
<!-- 在SD卡中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 向SD卡写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
注意:当开发者直接在Eclipse中运行Android应用程序 时,Eclipse默认启动的模拟器是不带SD卡的,为了让Eclipse启动的模拟器上带上SD卡,可以通过 Run As->Run Configurations菜单项打开如下图所示对话框,通过对话框的附加选项来使用SD卡(实际上就是在启动模拟器时 早呢更加-sdcard选项)。
代码使用示例:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".Read_InternalMemory" > <EditText android:id="@+id/EtExternal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="在这里输入内容" /> <Button android:id="@+id/BtnExternalSave" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写入数据" /> <Button android:id="@+id/BtnEXternalRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读取数据" /> <TextView android:id="@+id/TvExternalShow" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
MainActivity.java
private String fileName="text"; private TextView show; private EditText et; //判断手机上是否已经插了sdcard // if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) //获取当前sdcard的工作目录 File sdcard=Environment.getExternalStorageDirectory(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show=(TextView) findViewById(R.id.TvExternalShow); et=(EditText) findViewById(R.id.EtExternal); //写入数据 findViewById(R.id.BtnExternalSave).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { File myfile=new File(sdcard,"this is my file.txt"); if(!sdcard.exists()){ Toast.makeText(getApplicationContext(), "当前系统不具备SD卡目录", Toast.LENGTH_LONG).show(); return; } try { myfile.createNewFile(); Toast.makeText(getApplicationContext(), "文件已经创建完成", Toast.LENGTH_LONG).show(); FileOutputStream fos=new FileOutputStream(myfile); OutputStreamWriter osw=new OutputStreamWriter(fos); osw.write(et.getText().toString()); osw.flush(); osw.close(); fos.close(); Toast.makeText(getApplicationContext(), "文件已经写入完成", Toast.LENGTH_LONG).show(); } catch (IOException e) { e.printStackTrace(); } } }); //读取数据 findViewById(R.id.BtnEXternalRead).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { File myfile=new File(sdcard,"this is my file.txt"); try { FileInputStream fis=new FileInputStream(myfile); InputStreamReader isr=new InputStreamReader(fis, "UTF-8"); char[] input=new char[fis.available()]; isr.read(input); isr.close(); fis.close(); String in=new String(input); show.setText(in); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } });