一 数据流
概念
数据流(data stream)是一组有序,有起点和终点的字节的数据序列。(后面都简称“流”)
重点:有序,字节
分类
Android是使用java语言来编程的,所以其中的I/O操作和java中是一样的。I/O系统的设计目的是为了实现“文件”,“控制台”,“网络设备”等这些I/O设备间的通信。
在java 1.0中,java提供的类都是以字节(byte)为单位来操作数据,例如,FileInputStream和FileOutputStream。而到了java 1.1,为了与国际化进行接轨,在java io中添加了许多以字符为单位进行操作的类如StringReader,StringWriter。
按照不同的分类标准就产生了不同的分类。
输入流和输出流
按照流的方向分,分为输入流和输出流。这里入和出都是相对于内存而言的。
输入流:从文件流向内存 输出流:从内存流向文件
字节流和字符流
按照处理数据的单元分,可以分为字节流和字符流。
字节流:可以用于读写二进制文件及任何类型文件。
字符流:可以用于读写文本文件。
字节流和字符流的比较
字节流:字节作为最基本的数据单元,从而使任何文件都可以以字节流的形式传递。
字符流:目的是,方便我们处理文本文件,方便读取或者保存数据。本质是,根据字符编码规则,将字节数据进行了了处理,使我们得到想要的字符串。字符编码理解请参照“字符编码(ASCII,Unicode和UTF-8)”一文。
总结区别:
- 读写单位不同:字节流以字节(1 byte,1byte=8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的文件(如图片、视频等),而字符流只能处理包含字符类型的文件。
- 缓存:字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候是会用到缓冲区的,是通过缓冲区来操作文件。
二 具体的类
基类
所有的涉及的流类都位于java.io包中。
InputStream:所有以字节为单位输入流的基类。
OutputStream:所有以字节为单位输出流的基类。
Render:所有以字符为单位输入流的基类。
Writer:所有以字符为单位输出流的基类
2.1## 常用的几个
2.1.1输入流类
FileInputStream,InputStreamReader,BufferedReader
FileInputStream
字节流类,可以处理所有类型的文件,包括可以从网络上获取的文件。它处理的数据单位是字节。
关键字:输入,字节
InputStreamReader
字符流类,它用来将字节转化为字符。
关键字:输入,字节,字符
BufferedReader
字符流类,并带有缓存,将字符拼接为字符串。
关键字:输入,字符,字符串,缓存
使用示例
从一个文本文件中读取字符串(String):
//从File中读取String(方法一)
public String getStringFromFile1(){
String result = null;
File file = FileUtil.getNewsFile();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis,"UTF-8"));
StringBuffer sb = new StringBuffer();
String line = "";
while (line != null){
line = br.readLine();
if (TextUtils.isEmpty(line)){
break;
}
sb.append(line);
}
br.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
2.1.2输出流类
FileOutputStream
字节流类,可以处理所有类型的文件
简单的示例:
将String存入File中
//将String存入File中
public void saveStringToFile(String str){
try {
File file = FileUtil.getNewsFile();
FileOutputStream fos = null;
fos = new FileOutputStream(file);
fos.write(str.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
输入流和输出流简单使用示例
使用okhttp下载一个文件,下面是关键的代码
//-----------------省略代码---------------
final Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, final IOException e) {
//-----------------省略代码---------------
}
@Override
public void onResponse(Response response) throws IOException {
try {
InputStream is = response.body().byteStream();
FileOutputStream fs = new FileOutputStream(FileUtil.getFile());
byte[] bytes = new byte[1024];
int len = 0;
while ((len=is.read(bytes))!=-1){
fs.write(bytes);
}
is.close();
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//-----------------省略代码---------------
三 总结
数据I/O操作离不开流,而各种流“类”无非就是操作字节,字节数组,字符,字符数组,并提供相应辅助功能。
上面这是列举了几个平时比较常用的几个,其他的不经常用到,但是他们的功能实现的基础也是字节,字符,缓冲字节数组,缓冲字符数组,并提供了附加的功能。