一、IO流简介:
流的定义:流是指一连串流动的字符,是以先进先出方式发送信息的通道。
按流向分:输出流:OutputStream和Writer为基类
输入流:InputStream和Reader为基类
按处理数据单元划分:字节流:字节输入流:InputStream基类
字节输出流:OutputStream基类
字符流:字符输入流:Reader基类
字节输出流:Writer基类
(字节流是 8 位通用字节流,字符流是16位Unicode字符流)
1.1 InputStream
引入相关的类:InputStream ins =null;
构建输入流,例如FileInputStream:
ins =new FileInputStream(new File(path));
操控字节输入流的,所用的方法也是针对字节的。
常用方法:
返回值类型 | 方法名 | 方法简介 |
abstract int | read( ) | 从此输入流中读取下一个字节(此方法是抽象方法,子类必须实现该方法。 |
int | read(byte [ ] b ) | 从输入流中读取一定数量的字节,存储在参数指定的字节数组中。 |
int | read(byte [ ] b ,int off ,int len ) | 读到 len字节从输入流读入字节数组数据。 |
long | skip( long n ) | 跳过并丢弃 n字节从输入流中的数据。 |
int | available( ) | 返回此输入流下一个方法可以读取的字节数。 |
void | close( ) | 关闭流。 |
案例:
使用缓冲数组的方法读取文件内容,提高效率
public static void readArr() {
// 1、明确源数据源
File f = new File("F:/1/余文佳/1.txt");
// 2、构建流的对象
InputStream ins = null;
try {
ins = new FileInputStream(f);
// 3、声明缓冲数组
int i;// 表示读取了多少个字符到数组中
byte[] bt = new byte[5];// 字节缓冲数组
// 4、读取数据到数组中
//可以读多少写多少,转化成char类型,但是文件中都是英文,如果有中文则输出乱码
while ((i = (ins.read(bt))) != -1) {
for (int j = 0; j < i; j++) {
System.out.print((char) bt[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if (ins != null) {
ins.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
tips:
关于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常 读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅读Java的API说明就发现了,这个方法 并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。因此,如果要让程序读取count个字节,最好用以下代码:
byte[] b = new byte[count];
int readCount = 0; // 已经成功读取的字节的个数
while (readCount < count) {
readCount += in.read(bytes, readCount, count - readCount);
}
用这段代码可以保证读取count个字节,除非中途遇到IO异常或者到了数据流的结尾(EOFException)
1.2 OutputStream
常用方法:
返回值类型 | 方法名 | 方法简介 |
void | flush( ) | 刷新输出流,是缓存数据被写出来 |
void | write(byte [ ] b) | 写b.length 字节从指定的字节数组的输出流 |
void | write(byte [ ] b, int off, int len) | 写len字节从字节数组数据中到输入流 |
abstract int | write( int b ) | 将指定的字节写入该输出流中 |
void | close( ) | 关闭流 |
1.1.1 FileInputStream
FileInputStream是读取原始字节的图像数据流。读取字符流,考虑使用FileReader。
常用方法:
见InputStream中的方法
构建输入流:(准备工作)
FIle file =new File(path);
InputStream ins =null;
ins =new FileInputStream; //这里需要try catch
读取文件字符:
int i =0;
while( ( i=ins.read( ) ) != -1){
System.out.println( i );
} //输出的是自动转化的ASCII值,此处会抛出 IOException,需要try catch
或者提高效率,使用缓冲数组byte[ ] b,可读取英文文件,需要转化成char字符:
int len =0;
byte [ ]b=new byte [ 1024 ];//建立缓冲流数组
while((len=ins.read( b ))!= -1){
for( int j=0;j<len ;j++){
System.out.println( (char) bt [ j ] );
}
} //中间嵌套for循环,读多少输出多少,中文不可用,会输出乱码-->此处会抛出 IOException,需要try catch
完整案例:
package cn.pojo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) {
readByte();
readArr();
}
/**
* 读取字节
*/
public static void readByte() {
// 1、明确源数据源
File f = new File("F:\\1\\余文佳\\1.txt");
// 2、构建输入流对象
InputStream ins = null;
try {
ins = new FileInputStream(f);
int i;
// 3、 读取文件字符
while ((i = ins.read()) != -1) {
System.out.println("i=" + i);// 输出为转化的ascii码值
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4、关闭资源
if (ins != null) {
try {
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 2、使用缓冲数组的方法读取文件内容,提高效率
public static void readArr() {
// 1、明确源数据源
File f = new File("F:/1/余文佳/1.txt");
// 2、构建流的对象
InputStream ins = null;
try {
ins = new FileInputStream(f);
// 3、声明缓冲数组
int i;// 表示读取了多少个字符到数组中
byte[] bt = new byte[5];// 字节缓冲数组
// 4、读取数据到数组中
while ((i = (ins.read(bt))) != -1) {
for (int j = 0; j < i; j++) {
System.out.print((char) bt[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if (ins != null) {
ins.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
1.2.1 FileOutputStream
是OutputSTream的子类,主要功能是从源文件写入资料至指定文件中
构造方法:1、FileOutputStream( File file )// 创建“File对象”对应的“文件输入流”;默认“追加模式”是false,
即“写到输出的流内容”不是以追加的方式添加到文件中。若要追加则为(File file, true);
2、FileOutputStream( String path ) // 创建“文件(路径为path)”对应的“文件输入流”; (若没有,自动系统调用方法创建)
默认“追加模式”是false,即“写到输出的流内容”不是以追加的方式添加到文件中。 若要追加则为(String path, true);
try {
// 构造方法1
File file = new File("E:/java47.txt");
FileOutputStream fos1 = new FileOutputStream(file);
// File file = new File("E:/java47.txt");
// FileOutputStream fos1 = new FileOutputStream(file);
// 没有该文件会直接创建文件,但不能有多级目录,否则会报错,或者这只是个目录
// -->java.io.FileNotFoundException:E:\java\java48.txt (系统找不到指定的路径。)
// 构造方法2
FileOutputStream fos2 = new FileOutputStream("E:/java/java48.txt");// 规则如上
} catch (Exception e) {
e.printStackTrace();
}