File文件的写入
一、FileWriter 和BufferedWriter 结合写入文件
FileWriter是字符流写入字符到文件。默认情况下,它会使用新的内容代替文件原有的所有内容,但是,当指定一个true值作为FileWriter构造函数的第二个参数,它会保留现有的内容,并追加新内容在文件的末尾。
BufferedWriter:缓冲字符,是一个字符流类来处理字符数据。不同于字节流(数据转换成字节FileOutPutStream),可以直接写字符串、数组或字符数据保存到文件。
1 2 3 |
|
具体例子如下:
public static void writeInFileByfb() { File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt"); String content="要写入文件的新内容"; FileWriter fw=null; BufferedWriter bw=null; try{ if(!f.exists()){ f.createNewFile(); } fw=new FileWriter(f.getAbsoluteFile(),true); //true表示可以追加新内容 //fw=new FileWriter(f.getAbsoluteFile()); //表示不追加 bw=new BufferedWriter(fw); bw.write(content); bw.close(); }catch(Exception e){ e.printStackTrace(); } }
二、FileOutPutStream 字节流写入文件
文件输出流是一种用于处理原始二进制数据的字节流泪。 为了将数据写入到文件中,必须将数据转换为字节,并保存到文件。具体例子如下:
package com.joyplus.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class FileOutPutTest { public static void main(String[] args) { FileOutPutTest.writeInFileByfi(); } public static void writeInFileByfi(){ File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fi.txt"); FileOutputStream fos=null; try { if(!f.exists()){ f.createNewFile(); } fos=new FileOutputStream(f); String content="要写入的新内容!"; fos.write(content.getBytes()); } catch (IOException e) { e.printStackTrace(); }finally{ if(fos!=null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
三、RandomAccessFile 写入文件
RandomAccessFile的唯一父类是Object,与其他流父类不同。是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的.
如下例子是RandomAccessFile如何进行写入文件的例子:
public static void writeInFileByRdA(){ String content="randowAccessFile"; try{ // 打开一个随机访问文件流,按读写方式 RandomAccessFile randomFile = new RandomAccessFile("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt", "rw"); // 文件长度,字节数 long fileLength = randomFile.length(); //将写文件指针移到文件尾。 randomFile.seek(fileLength); randomFile.writeBytes(content); randomFile.close(); }catch(Exception e){ e.printStackTrace(); } }
文件的读取
一、FileInputStream 字节流读取文件 【注意:读取中文的时候会乱码】
具体代码如下:
//按照字节读取文件内容 public static String readFileByByte(){ String s=""; File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt"); InputStream in=null; try{ in=new FileInputStream(f); int tempByte; while((tempByte=in.read())!=-1){ System.out.println(tempByte); s+=tempByte; } in.close(); }catch(Exception e){ e.printStackTrace(); } System.out.println("content:"+s); return s; }
二、InputStreamReader 字符流读取文件内容
//按照字符读取文件内容 public static String readFileByChar(){ String s=""; File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt"); Reader rdr=null; try{ rdr=new InputStreamReader(new FileInputStream(f)); int temp; while((temp=rdr.read())!=-1){ //对于window下,\r\n这两个字符在一起时,表示一个换行。 //但是如果这两个字符分开显示时,会换两行。 //因此,屏蔽掉\r,或者屏蔽掉\n。否则,将会出现很多空行 if(((char)temp)!='\r'){ s+=(char)temp; } } }catch(Exception e){ e.printStackTrace(); }finally{ try { rdr.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println(s); return s; }
三、BufferedReader 以行为单位读取文件内容
//按照行读取文件 public static String readFileByLine(){ String s=""; File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt"); BufferedReader br=null; try{ System.out.println("按照行读取文件内容"); br=new BufferedReader(new FileReader(f)); String temp; while((temp=br.readLine())!=null){ s+=temp; } }catch(Exception e){ e.printStackTrace(); }finally{ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("file content:"+s); return s; }
四、随机读取文件中的部分内容: RandomAccessFile
//随机行读取文件 public static String readFileByRand(){ String s=""; File f=new File("E:\\Java\\jmoa\\TestDiff\\src\\test\\resource\\test_fb.txt"); RandomAccessFile raf=null; try{ //打开一个文件流, 按只读方式 raf=new RandomAccessFile(f.getName(), "r"); //文件长度,字节数 long fileLength=raf.length(); //读文件的起始位置 int beginIndex=(fileLength>4)?4:0; //将读文件的开始位置移到beginIndex位置 raf.seek(beginIndex); byte[] bytes=new byte[10]; int byteread=0; //一次读10个字节,如果文件内容不足10个字节,则读剩下的文字。 //将一次读取的字节数赋给byteread while((byteread=raf.read(bytes))!=-1){ System.out.write(bytes,0,byteread); } }catch(Exception e){ e.printStackTrace(); }finally{ if(raf!=null){ try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } //System.out.println("文件内容:"+s); return s; }
补充的文件知识:
/** * 显示输入流中还剩的字节数 */ private static void showAvailableBytes(InputStream in) { try { System.out.println("当前字节输入流中的字节数为:" + in.available()); } catch (IOException e) { e.printStackTrace(); } }
文件的下载
// 在线打开方式 下载 public void downLoad(String filePath, HttpServletResponse response,String fileNewName) throws Exception { File f = new File(filePath); OutputStream out = response.getOutputStream(); if (!f.exists()) { response.setCharacterEncoding("UTF-8"); String notFileHtml=getNotFileHtml(filePath,"文件找不到"); out.write(notFileHtml.getBytes("UTF-8")); out.flush(); return; } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; response.reset(); // 非常重要 response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + fileNewName); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.close(); }
关于Android的File存储,这里先说下Java中的File类,根据面向对象的思想,Java中对文件的操作也进行了对象的封装,这个操作文件的类就是File类,File提供了丰富的api来进行文件的操作,比如常见的createNewFile(),mkdir(),mkdirs(),exists(),isFile(),isDictory(),renameto(),delete(),getName(),getPath()....方法比较多,读者可以自行通过api文档查看,同样这一套的文件操作在Android中也适用。
File构造函数
/** *这里通过将给定路径名字符串转换为抽象路径名来创建一个新File实例。 *然后执行file.createNewFile();如果该文件存在,则创建失败,不存在则创建,返回一个boolean值 */ File file=new File(String pathname);
/** *这里根据parent抽象路径名和child路径名字符串创建一个新File实例。 *执行file.createNewFile();如果parent抽象路径名不存在,或者文件已经创建过,依然不能创建成功。 */ File file=new File(File parent,String child);
/** *根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 *执行file.createNewFile();如果parent抽象路径名不存在,或者文件已经创建过,依然不能创建成功。 */ File file=new File(String parentpath,String child);
File常用方法
方法说明
除了这两个方法外,Context对象还提供了其他几个用于对文件操作的方法,如下所示
在使用openFileOutput方法打开文件以写入数据时,需要指定打开模式。默认为零,即MODE_PRIVATE。不同的模式对应的的含义如下:
常量 含义
MODE_PRIVATE
默认模式,文件只可以被调用该方法的应用程序访问
MODE_APPEND
如果文件已存在就向该文件的末尾继续写入数据,而不是覆盖原来的数据。
MODE_WORLD_READABLE
赋予所有的应用程序对该文件读的权限。
MODE_WORLD_WRITEABLE
赋予所有的应用程序对该文件写的权限。
但是Android 4.2开始,Android不推荐使用,MODE_WORLD_READABLE ,MODE_WORLD_WRITEABLE 这两种模式。
应用私有存储(内置存储)
获取方式:
Context.getFileDir():获取内置存储下的文件目录,可以用来保存不能公开给其他应用的一些敏感数据如用户个人信息
Context.getCacheDir():获取内置存储下的缓存目录,可以用来保存一些缓存文件如图片,当内置存储的空间不足时将系统自动被清除
绝对路径:
Context.getFileDir():/data/data/应用包名/files/
Context.getCacheDir():/data/data/应用包名/cache/
写权限:不需要申请
这是手机的内置存储,没有root的过的手机是无法用文件管理器之类的工具查看的。而且这些数据也会随着用户卸载App而被一起删除。这两个目录其实就对应着设置->应用->你的App->存储空间下面的清除数据和清楚如下图所示
应用扩展存储(SD卡)
获取方式:
Context.getExternalFilesDir():获取SD卡上的文件目录
Context.getExternalCacheDir():获取SD卡上的缓存目录
绝对路径:
Context.getExternalFilesDir():SDCard/Android/data/应用包名/files/
Context.getExternalCacheDir():SDCard/Android/data/应用包名/cache/
写权限:
API < 19:需要申请
API >= 19:不需要申请
既然是SD卡上的目录,那么是可以被其他的应用读取到的,所以这个目录下,不应该存放用户的敏感信息。同上面一样的,这里的文件会随着App卸载而被删除,也可以由用户手动在设置界面里面清除。
公共存储(SD卡)
获取方式:Environment.getExternalStorageDirectory()
绝对路径:SDCard/你设置的文件夹名字/
写权限:需要申请
根据最开始提到的规则,其实如果仅仅是做了简单的图片缓存工作,那么我们应该把图片缓存放到/data/data/应用包名/cache/或者SDCard/Android/data/应用包名/cache/,因为在6.0系统(API23)时,不需要申请权限就可以向这两个目录写入文件。而且/data/data/应用包名/cache/目录,是内置存储的应用私有缓存目录,在系统空间不够时还会被自动清除,对于图片缓存来讲也是一个不错的管理策略,不过谷歌建议我们最好还是自己实现缓存清除管理,例如用DiskLruCache。
参考文章:http://unclechen.github.io/2016/03/06/Android6.0%E6%9D%83%E9%99%90%E9%80%82%E9%85%8D%E4%B9%8BSD%E5%8D%A1%E5%86%99%E5%85%A5/
2018年07月16日 10:32:11 长眠于心 阅读数:600
一.Android file类
在开发Android应用时免不了会跟文件打交道,本篇文章记录总结自己常用到的文件操作,数据的存储有多种方式,比如数据库存储、SharedPreferences存储、文件存储等;这里我们将要介绍最简单的文件存储方式;文件存储简单的来说就是一般的JAVASE中的IO流,只是把他应用于Android手机中而已。
二.Android file类使用
File文件的存储需要在程序中使用sdcard进行数据的存储,需要在AndroidMainfset.xml文件中进行权限的配置:
1.SDCard中创建与删除文件权限:
2.SDCard写入数据权限
代码如下:
File类语法
1.File(String pathname)
File file = new File ("/mnt/sdcard/test.txt");
2.File(String dir, String subpath)
File file = new File("/mnt/sdcard/temp", "test.txt");
File类常用方法
boolean exists() 测试文件是否存在
boolean delete() 删除此对象指定的文件
boolean createNewFile() 创建新的空文件
boolean isDirectory() 测试此File对象表示的文件是否是目录
boolean mkdir() 创建由该File对象表示的目录
boolean mkdirs() 创建包括父目录的目录
String getAbsolutePath() 返回此对象表示的文件的绝对路径名
String getName() 返回此对象表示的文件的名称
String getParent() 返回此File对象的路径名的上一级,若路径名没有上一级,则返回null
使用mkdir创建由该File对象表示的目录
package com.example.cxy.file; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.io.File; import java.io.IOException; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ btn= (Button) findViewById(R.id.button); btn.setOnClickListener(this); } @Override public void onClick(View v) { //先实例化一个file对象,参数为路径名 File file = new File("/mnt/sdcard/Tenect/chenxiaoyang.txt"); //File file = new File("/mnt/sdcard/Tenect","chenxiaoyang.txt"); try { //判断文件是否存在 if (file.exists()){ //文件如果存在删除这个文件 file.delete(); Toast.makeText(MainActivity.this, "删除成功了", Toast.LENGTH_SHORT).show(); }else{ //创建一个新的文件 file=new File("/mnt/sdcard/Tenect"); //先创建文件夹 file.mkdir(); //创建这个文件 file = new File("/mnt/sdcard/Tenect/chenxiaoyang.txt"); file.createNewFile(); Toast.makeText(MainActivity.this, "创建成功了", Toast.LENGTH_SHORT).show(); } //获取当前file文件的绝对路径 Log.i("$$$",file.getAbsolutePath()); //获取当前file文件的名字,包括后缀名 Log.i("$$$",file.getName()); //获取当前file文件的以上所有级的目录 Log.i("$$$",file.getParent()); //测试此file文件是否是一个目录 boolean directory=file.isDirectory(); Log.i("$$$",String.valueOf(directory)); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "失败了", Toast.LENGTH_SHORT).show(); } } }
使用mkdirs创建包括父目录的目录
package com.example.cxy.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.io.File; import java.io.IOException; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inintView(); } private void inintView() { btn= (Button) findViewById(R.id.button); btn.setOnClickListener(this); } @Override public void onClick(View v) { //先实例化一个file对象,参数为路径名 File file=new File("/mnt/sdcard/tmp/one/two/three","test.txt"); try { //判断文件是否存在 if(file.exists()){ //文件如果存在删除这个文件 file.delete(); Toast.makeText(MainActivity.this,"删除成功", Toast.LENGTH_SHORT).show(); }else{ //创建一个新的文件 file=new File("/mnt/sdcard/tmp/one/tow/three"); //先创建文件夹,mkdirds可直接创建多级文件夹 file.mkdirs(); //创建这个文件 file=new File("/mnt/sdcard/tmp/one/tow/three/test.txt"); file.createNewFile(); } } catch (IOException e) { e.printStackTrace(); } } }