文件通常是由一连串的字节或字符构成,组成文件的字节序列称为字节流,组成文件的字
符序列称为字符流
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);
}
文件输入流,用于从文件读取数据,它的对象可以用关键字 new 来创建,它有多种构造方法可用来创建对象。
创建输入流的方式:
InputStream f = new FileInputStream("/data/data/包名/file/hello.text");
或
File f = new File("/data/data/包名/file/hello.text");
InputStream out = new FileInputStream(f);
文件输出流,用于向文件写入数据,如果该流在打开文件进行输出前,目标文件不存在,该流不会创建该文件,并抛出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
在构造方法中,如果将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
常用于用于处理纯文本
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的讲解及使用你一定得看看,写的非常详细