在java中,将通过不同输入输出设备(键盘,内存,显示器,网络等)之间的数据传输抽象表述为"流"
java中的流都位于java.io包中,成为IO(输入,输出)流
按照 操作数据的不同 分为字节流 和字符流
按照 数据传输的方向 分为输入流 和输出流
程序从输入流中读取数据 想输出流总写入数据.
在IO 包中
字节流的输入输出 分别用 java.io.InputStream 和java.io.OutputStream表示
字符流的输入和输出 分别用java.io.Reader 和java.io.Writer表示
8.1.1字节流的概念
在计算机中, 所有的文件都是以二进制(字节)形式 存在
针对字节的输入和输出提供的流 称为字节流.
在JDK中, 提供了两个抽象类InputStream和OutputStream, 它们是字节流的顶级父类.
InputStream的常用方法
int read() : 从输入流中读取一个8位的字节,把它转化成0~255之间的整数,并返回这个整数
int read(byte[] b) :从输入流读取若干个字节,把它们保存到参数b指定的字节数组中,返回整数表示读取的字节数
int read (byte[] b,int off,int len) :从输入流读取若干个字节,把它们保存到b字节数组,off表示指定字节数组的下标,len表示读取的字节数目
void close()
前三个方法是用来 读取 数据用的 , 最后一个用来关闭输入流. 节约资源
OutputStream的常用方法
void write(int b)
void write(byte[] b)
void write(byte[] b, int off, int len)
void flush()
void close()
8.1.2字节流读写文件
在操作文件时 ,最常见的就是从文件中读取数据并将数据写入文件,即文件的读写.
针对文件的读写,JDK专门提供了两个类,分别是FileInputStream和FileOutputStream
public class Demo01 {
public static void main(String[] args) throws IOException {
// 创建一个文件字节输入流
FileInputStream in = new FileInputStream("E:\\a.txt");
// 读取输入流中的数据
int b = 0; // 返回为读取到的第一个byte的int表示形式,read中内置一个计数器,跳到下一个
while(true){
b = in.read();
if(b==-1){
break;
}
System.out.println(b);
}
in.close();
}
}
最后显示结果是,a.txt文件中 所有字节对应的十进制数
注意:在读取文件数据时,必须保证文件是存在并且可以读的,否则会抛出,FileNotFoundException
public class Demo02 {
public static void main(String[] args) throws Exception {
//创建一个字节输出流
FileOutputStream out = new FileOutputStream("E://a.txt");
//定义一个要写入的字符串
String str ="coming Baby";
//把字符串转化成 字节数组
byte[] byt = str.getBytes();
out.write(byt); //将一个字节数组写入
//也可以将数组循环一个一个写入
out.close();
}
}
注意, 在已经存在的文件中写入数据, 会覆盖原来的内容
若希望在原来的内容上追加内容, 在创建输出流对象时候,
选择 new FileOutputStream(file, append) 这个构造函数
8.1.3文件的拷贝
在应用程序中文件通常是成对出现的,即输入流和输出流一起用.
案例:
//IO 字节流 的拷贝
public class Demo03 {
public static void main(String[] args) throws Exception {
// 拷贝 E:\\a.txt 文件 去 D:\\copy.txt
// 创建一个输入流 读取 内容
FileInputStream in = new FileInputStream("E:\\a.txt");
// 创建一个输出流 写入数据
FileOutputStream out = new FileOutputStream("D:\\copy.txt");
int b = 0; // 这种方法是一个字节一个字节的 读和写,效率低下
while(true){
b = in.read();
if(b==-1){
break;
}
out.write(b);
}
out.close(); //先关写出去的流
in.close(); //后关读进来的流
}
}
8.1.4字节流的缓冲区
当通过流的方式拷贝文件时,为了提高效率也可以定义一个字节数组作为缓冲区.在拷贝文件时,可以一次性读取多个字节的数据.
并保存在字节数组中,然后将字节数组中的数据一次性写入文件.
public class Demo04 {
public static void main(String[] args) throws IOException {
// 拷贝 E:\\a.txt 文件 去 D:\\copy.txt
// 创建一个输入流 读取 内容
FileInputStream in = new FileInputStream("E:\\a.txt");
// 创建一个输出流 写入数据
FileOutputStream out = new FileOutputStream("D:\\copy.txt");
//定义一个字节数组作为缓冲区
byte[] buff = new byte[1024];
//定义一个int类型的变量len记住读取读入缓冲区的字节数
int len;
while((len=in.read(buff))!=-1){
out.write(buff, 0, len);
}
out.close();
in.close();
}
}
8.1.5 装饰设计模式
------
8.1.6字节缓冲流
-----
8.2.字符流
8.2.1字符流定义基本用法
与字节流一样,字符流也有两个顶级父类 分别是 Reader 和 Writer.
其中Reader是字符输入流 Writer是字符输出流
它们的常用子类中FileReader和FileWriter用于读写文件
8.2.2 字符流操作文件
从输入流中读数据
public class Demo05 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileReader fr = new FileReader("E:\\a.txt");
int ch;
while((ch=fr.read())!=-1){
System.out.println((char)ch);
}
//为什么这种方法不行?
// while(fr.read()!=-1){
// System.out.println((char)fr.read());
// }
fr.close();
}
}
在输出流中写数据
------