I/O流(1)--字节流
数据处理分类:
I/O流:Input/Output
- 流的本质 :数据传输。【根据数据传输特性将流抽象为各种类】
- 流的作用:为数据源和目的地建立一个输送通道。
- 输出流:程序(内存) ——> 外界设备【把程序中的信息输出到文件中】
- 输入流:外界设备 ——> 程序(内存)【将文件中的信息读取到程序中】
流的分类
按照操作单元划分【处理数据类型】,可以划分为字节流和字符流
- 字节流:处理字节相关,如声音或者图片等二进制,主要由InputStream/OutputStream作为基类
- 字符流:处理字符相关,如处理文本数据(如txt文件),主要以Reader/Writer作为基类
- 区别:(1)二者所操作的数据单元不同,字节流操作的数据单元是8位的字节;字符流操作的是数据单元为16的字符。
(2)字节流在操作是本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。 - I/O流相关类
InputStream
- InputStream是输入字节流的父类,是一个抽象类,一般使用它的子类。
- 常用方法:
int read():读取一系列字节并存储到一个数组buffer,返回实际读取的字节数,如果读取前已到输入流的末尾返回-1。
int read(byte[] buf): 读取length个字节并存储到一个字节数组buffer,从off位置开始存,最多len, 返回实际读取的字节数,如果读取前以到输入流的末尾返回-1。
long skip(long n):从输入流中跳过并丢弃n个字节的数据。
int available():返回这个流中有多少个字节数,可以把buf数组长度定义为这个。
void close() :关闭输入流并释放与该流关联的系统资源 - 常见子类。
- FileInputStream:抽象类InputStream用来具体实现类的创建对象,文件字节输入流,对文件数据以字节的形式进行读取操作。
public static void main(String[] args) throws IOException {
String path = "D:\\java";
String name = "a.txt";
File file = new File(path,name);
InputStream inputStream = new FileInputStream(file);
//读测试
// testRead(inputStream); //结果一个字节
//跳过测试
// testSkip(inputStream); //加上读测试 120 x 2 108 l
//
testReadByteArr(inputStream);
}
public static void testRead(InputStream inputStream)throws IOException{
//对于汉字等,uncode中的字符不能正常读取,只能以乱码的形式显示
//一个汉字不止一个字节
int read = inputStream.read();
System.out.println(read);
System.out.println((char)read);
inputStream.close();
}
public static void testSkip(InputStream inputStream)throws IOException{
long skipSize = inputStream.skip(2);
System.out.println(skipSize);
int read = inputStream.read();
System.out.println(read);
System.out.println((char)read);
inputStream.close();
}
public static void testReadByteArr(InputStream inputStream)throws IOException{
//如果buff的长度为0,则不读取任何字节并返回0
//然后每次读取的字节数,最多读取buff的长度
// byte[] buff = new byte[8];
byte[] buff = new byte[inputStream.available()];
//
int length;
//循环读取文件内容,输入流中最多读取buff.length 个字节数据读入一个buff数组中
//返回类型是读取到的字节数
//如果这个缓冲区没有满的时候,则返回真的字节数
while ((length =inputStream.read(buff)) !=-1 ){
System.out.println(new String(buff,0,length));
// System.out.print(new String(buff,0,length));
//如果乱码,指定编码格式,看文件编码 中文乱码 【多推荐GBK/UTF-8】
//System.out.print(new String(buff,0,length,"UTF-8"));
}
inputStream.close();
}
OutputStream
- OutputStream是输出字节流的父类,是一个抽象类,一般使用它的子类。
- 常用方法:
void write(int b):将指定的字节写入输出流
void write(byte[] b):将b.length个字节的byte数组写入当前输出流
void flush():write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容写⼊
⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓冲区数据。
void close():关闭输入流并释放与该流关联的系统资源 - 常见子类
- FileOutputStream:抽象类InputStream用来具体实现类的创建对象,文件字节输出流,对文件数据以字节的形式进行输出操作。
public static void main(String[] args) throws IOException {
String path = "D:\\java";
String name = "a.txt";
String target = "target.txt";
File file = new File(path,name);
InputStream inputStream = new FileInputStream(file);
//会自动创建文件,但是不会创建多级目录下的文件
// OutputStream outputStream =
// new FileOutputStream(path+ File.separator+target);
//不覆盖文件,追加数据
OutputStream outputStream =
new FileOutputStream(path+ File.separator+target,true);
//单个读取测试
// testOut(inputStream,outputStream);
//数组读取测试
testOutBuf(inputStream,outputStream);
}
//单个字节读取, 中文会有问题
public static void testOut(InputStream inputStream,OutputStream outputStream)throws IOException{
int value = 0;
while (value != -1){
value = inputStream.read();
outputStream.write(value);
}
//最后记得关闭流 后开先关
inputStream.close();
outputStream.close();
}
public static void testOutBuf(InputStream inputStream,OutputStream outputStream)throws IOException{
byte[] buff = new byte[1024];
int length;
while ((length = inputStream.read(buff))!=-1){
outputStream.write(buff,0,length);
}
inputStream.close();
outputStream.close();
}