概念
java的io是实现输入和输出的基础,可以方便的实现数据的输入和输出操作。在java中把不同的输入/输出源(键盘,文件,网络连接等)抽象表述为“流”(stream)。通过流的形式允许java程序使用相同的方式来访问不同的输入/输出源。stram是从起源(source)到接收的(sink)的有序数据。
IO流的分类
按照不同的分类方式,可以把流分为不同的类型。常用的分类有三种:
- 按照流的流向分,可以分为输入流和输出流。
-
输入流: 只能从中读取数据,而不能向其写入数据。
-
输出流:只能向其写入数据,而不能向其读取数据。
2.按照操作单元划分,可以划分为字节流和字符流。
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
3.按照流的角色划分为节点流和处理流。
文件字节输入流读取文件内容
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
class FileInputStreamDemo01 {
public static void main(String[] args) {
File file = new File("C:\\Users\\Administrator\\Desktop\\2017-08-16\\2017-08-16.java");
// 1.创建流对象
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
// 2.创建一个缓存字节的容器数组
byte[]buf = new byte[1024];
// 3.定义一个变量,保存实际读取的字节数
int hasRead = 0;
// 4.循环读取数据
// while (true) {
// hasRead = fis.read(buf);
// if (hasRead==-1) {
// break;
// }
5.操作保存数据的数组
// String msg = new String(buf, 0,hasRead);
// System.out.print(msg);
// }
while ((hasRead = fis.read(buf))!=-1) {
String str = new String(buf,0,hasRead);
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
// 6.关闭流
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件字节输出流写入文件内容
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
// 1.选择流:创建流对象
FileOutputStream fos =null;
try {
fos = new FileOutputStream(new File("c:\\read.txt"),true);
// 2.准备数据源,把数据源转换成字节数组类型
// String msg = "春夜喜雨\n好雨知时节,当春乃发生。\n随风潜入夜,润物细无声。";
String msg = "\n野径云俱黑,江船火独明。\n晓看红湿处,花丛锦官城。";
byte[] data = msg.getBytes();
// 3.通过流向文件当中写入数据
fos.write(data, 0, data.length);
// 4.刷新流
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos!=null) {
// 5.关闭流
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字节字符区别
节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
· 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
节点流
字节数组流(内存流)
ByteArrayInputStream
ByteArrayOutputStream
因为内存输出流当中又新增的方法,不能使用多态,不能够让父类的引用指向之类的对象。
作用:可以在循环当中把所有的数据存放到统一的容器当中,然后在循环结束之后可以把容器当中所有的内容一起取出来。
注意事项:
内存流属于内存当中的资源,所以数据量不要过大,如果太大,会造成内存溢出的错误。
打印流
打印流是输出信息最方便的类,主要包含字节打印流(PrintStream)和字符打印流(PrintWriter)
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class print_stream{
public static void main(String[] args) throws Exception{
File f = new File("D:" + File.separator + "test.txt");
PrintStream ps = null;
OutputStream out = new FileOutputStream(f);
//通过 FileOutputStream 的实例化,意味着所有的输出是向文件中打印
ps = new PrintStream(out);
ps.print("Hello");
ps.println("World!!!");
ps.print("1 + 1 = " + 2);
ps.close();
}
}
对象序列化
将对象转换成字节序列的过程,就是对象序列化过程。
- 将字节序列恢复为对象的过程称之为对象的反序列化。
- 作用:保留对象(引用数据类型数据的)类型+数据。
- 序列化流 :输出流 ObjectOutputStream writeObject()
- 反序列化流: 输入流 ObjectInputStream readObject()
对象序列化的步骤:
- 1.创建对象输出流,在构造方法当中可以包含其他输出节点流,如文件输出流。
- 2.把对象通过writeObject的方式写入。
- 对象反序列化的步骤:
- 1.创建对象输入流,在构造方法当中可以包含其他的输入节点流,如文件输入流
- 2.通过readObject()方法读取对象。