android 知识点总结---文件的处理(流操作)

文件通常是由一连串的字节或字符构成,组成文件的字节序列称为字节流,组成文件的字
符序列称为字符流

Java IO中用于读写文件的四个抽象类:Reader,Writer,InputStream,OutputStream。
根据流所处理的数据类型分为两类:
(1)字节流:用于处理字节数据。(InputStream,OutputStream)
(2)字符流:用于处理字符数据,Unicode字符数据。(Reader,Writer)

字节流

可用于处理任何文件,如图片,音频,视频等,

InputStream : 是所有字节输入流的父类,一般使用它的子类FileInputStream等,它能输入字节流;(将磁盘、内存的数据读取到程序中)

     基本用法:

      int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
      int read(byte[]?b) :从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。如果 b 的长度为 0,则不读取任何字节并返回 0;如果返回-1,表示读到了输入流的末尾。
      int read(byte[]?b, int?off, int?len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

OutputStream : 是所有字节输出流的父类,一般使用它的子类FileOutputStream等,它能输出字节流;(将程序输出到磁盘、内存中)

     基本用法:

     abstract void write(int?b):往输出流中写入一个字节。
     void write(byte[]?b) :往输出流中写入数组b中的所有字节。
     void write(byte[]?b, int?off, int?len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。

    其它方法:
    void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
     void close() :关闭输出流,释放和这个流相关的系统资源。

//将输入流每次读1024个字节读出,缓存到buf中,length是实际读的字节数,然后将buf写入到输出流
int length = -1;
byte[] buf = new byte[1024];
while ((length = in.read(buf)) != -1) {
          out.write(buf, 0, length);
}

 

1.  FileInputStream

文件输入流,用于从文件读取数据,它的对象可以用关键字 new 来创建,它有多种构造方法可用来创建对象。

创建输入流的方式:

InputStream f = new FileInputStream("/data/data/包名/file/hello.text");

File f = new File("/data/data/包名/file/hello.text");
InputStream out = new FileInputStream(f);

2. FileOutPutStream

文件输出流,用于向文件写入数据,如果该流在打开文件进行输出前,目标文件不存在,该流不会创建该文件,并抛出FileNotFindException

创建输出流的方式:

OutputStream f = new FileOutputStream("/data/data/包名/file/hello.text")

File f = new File("/data/data/包名/file/hello.text");
OutputStream f = new FileOutputStream(f);

写数据

File f = new File("d:" + File.separator+"test.txt");
OutputStream out=new FileOutputStream(f);//如果文件不存在会自动创建
String str="Hello World";
byte[] b=str.getBytes();
out.write(b);//因为是字节流,所以要转化成字节数组进行输出
out.close();

也可以一个字节一个字节进行输出,如下:

File f = new File("d:" + File.separator+"test.txt");
OutputStream out=new FileOutputStream(f);//如果文件不存在会自动创建
String str="Hello World";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++){
    out.write(b[i]);
}
out.close();

在构造方法中,如果将append的值设置为true,则表示在文件的末尾追加内容。

File f = new File("d:" + File.separator+"test.txt");
OutputStream out=new FileOutputStream(f,true);//追加内容
String str="\r\nHello World";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++){
    out.write(b[i]);
}
out.close();

 

字符流

常用于用于处理纯文本

Reader : 所有字符输入流的父类,它以字符流的形式输入

Writer : 所有字符输出流的父类,它以字符流的形式输出

FileReader:用来读取字符文件的便捷类

InputStreamReader:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

FileWriter:用来写入字符文件的便捷类

OutputStreamWriter:OutputStreamWriter是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

BufferedWriter:从字符输出流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效写入。

输入流读数据

读取单个字符,公有方法:

int read() 

将字符读入数组的某一部分,InputStreamReader和BufferedReader有

int read(char[] cbuf, int off, int len) 

读取一个文本行,只有BufferedReader有

String readLine() 

使用时可以先用FileReader或InputStreamReader获得字符流,再用BufferedReader封装后每行读取:

********************FileReader******************************************
FileReader r = new FileReader(file);
BufferedReader br = new BufferedReader(r);
//由于每次只能读一行,就让其不断地读
StringBuffer msg = new StringBuffer();
String s;
while ((s = br.readLine()) != null) {
    msg = msg.append(s+“\n”); //必须要加\n 否则全部数据变成一行
}
//别忘了释放资源
r.close;
br.close;

********************InputStreamReader***********************************
InputStreamReader isr = new InputStreamReader(is, "UTF-8");//指定编码格式
BufferedReader bfr = new BufferedReader(isr);
String in = "";
while ((in = bfr.readLine()) != null) {
          Log.i(TAG, in);
}
//别忘了释放资源
bfr.close();
isr.close();

输出流写数据

写入单个字符

write(int c):

写入字符串的某一部分

write(String str, int off, int len)

刷新此输出流,并强制将所有已缓冲的输出字节写入该流中

flush()

关闭此流,但要先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。关闭以前关闭的流无效

 

缓冲流

字节缓冲流: BufferedInputStream,BufferedOutputStream 
字符缓冲流:BufferedReader ,BufferedWriter 
缓冲流是对流的操作的功能的加强,提高了数据的读写效率。既然缓冲流是对流的功能和读写效率的加强和提高,所以在创建缓冲流的对象时应该要传入要加强的流对象。

//1.指定要读 的文件目录及名称
        File file =new File("文件路径");
        //2.创建文件读入流对象
        FileInputStream fis =new FileInputStream(file);
        //3.创建缓冲流对象加强fis功能
BufferedInputStream bis =new BufferedInputStream(fis); 
        //4.定义结束标志,可用字节数组读取
        int i =0 ;
        while((i = bis.read())!=-1){ 
            //i 就是从文件中读取的字节,读完后返回-1
        }
        //5.关闭流
        bis.close();
        //6.处理异常

转换流

这类流是用于将字符转换为字节输入输出,用于操作字符文件,属于字符流的子类,所以后缀为reader,writer;前缀inputstream,outputstream;注 :要传入字节流作为参数 
InputStreamReader: 字符转换输出流 
OutputStreamWriter:字符转换输入流

需求:读取键盘输入的一行文本,再将输入的写到本地磁盘上

//1.获取键盘输入的字节流对象in
InputStream in = System.in; 
/*2.用转换流将字节流对象转换为字符流对象,方便调用字符缓冲流的readeLine()方法*/
InputStreamReader isr = new InputStreamReader(in);
 
/*3.现在isr是字符流,可以作为参数传入字符缓冲流中*/
BufferedReader br = new BufferedReader(isr);

try {
    //4.创建字符转换输出流对象,方便把输入的字符缓冲流转换为字节流写入文件中
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File(fileName)));
    //5.可以调用字符缓冲流br的readLine()方法度一行输入文本
    String line = null;
    while ((line = br.readLine()) != null) {
        osw.write(line);
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

 
 
注:InputStreamReader isr =new InputStreamReader(new "各种类型的字节输入流都行即是:后缀为InputStream就行");
OutputStreamWriter osw =new OutputStreamWriter(new 
    "后缀为OutputStream就行"); 

内存操作流

ByteArrayInputStream和ByteArrayOutputStream

String str="HELLO WORlD!!!";
InputStream input=new ByteArrayInputStream(str.getBytes());
OutputStream output=new ByteArrayOutputStream();
int temp=0;
while((temp=input.read())!=-1){
    output.write(Character.toLowerCase(temp));
}
input.close();
output.close();
System.out.println(output.toString());

具体实例:

压缩图片到合适大小:

public static Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 90;
        int length = baos.toByteArray().length / 1024;
        Log.e(TAG,"length="+length);
        if (length>5000){
            //重置baos即清空baos
            baos.reset();
            //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.JPEG, 10, baos);
        }else if (length>4000){
            baos.reset();
            image.compress(Bitmap.CompressFormat.JPEG, 20, baos);
        }else if (length>3000){
            baos.reset();
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        }else if (length>2000){
            baos.reset();
            image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
        }

        Log.e(TAG,"baos.toByteArray().length="+baos.toByteArray().length);
        //循环判断如果压缩后图片是否大于1M,大于继续压缩
        while (baos.toByteArray().length / 1024>1024) {
            //重置baos即清空baos
            baos.reset();
            //这里压缩options%,把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);
            //每次都减少10
            options -= 10;
        }
        //把压缩后的数据baos存放到ByteArrayInputStream中
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        //把ByteArrayInputStream数据生成图片
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
        return bitmap;
    }

参考文档:

Android中文件的读写(一)----流操作

Android中的IO输入输出流

另:

这篇IO流File的讲解及使用你一定得看看,写的非常详细

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值