1、生活中的流:
水流,车流,流水线。
2、流的概念:
流是一种载体,用于装载事物,并根据一定方向进行移动。
3、Java中的流:
根据传输数据载体不同分成两种字节流,字符流,装载数据,从内存传递到硬盘流称之为输出流,从硬盘传输到内存的流称之为输入流。
4、学习流方式:
从简单到复杂,先学字节流再学字符流。从上往下,先学IO流根再学其子类。
字节流
1、OutputStream:字节输出流
(1)API介绍
(2)功能方法
2、FileOutputStream类
(1)API介绍
(2)构造方法
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class Demo3_FileOutputStream {
public static void main(String[] args) throws FileNotFoundException {
//构造方法
//1、FileOutputStream(String) 创建字节输出流,如果文件存在则清空文件内容。如果文件不存在则创建文件
/*
返回结果
FileNotFoundException:文件路径不存在时,就出异常。
*/
FileOutputStream out = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
System.out.println(out);//java.io.FileOutputStream@610455d6
//2、FileOutputStream(String,boolean) 创建字节输出流,如果参数2为true且文件存在则不会清空内容。如果文件不存在则创建文件。
/*
返回结果
FileNotFoundException:文件路径不存在时,就出异常。
*/
FileOutputStream out2 = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt", true);
System.out.println(out2);//java.io.FileOutputStream@610455d6
//3、FileOutputStream(File) 创建字节流对象之前,File对象还可以执行File方法。如果文件存在则清空文件内容。如果文件不存在则创建文件
FileOutputStream out3 = new FileOutputStream(new File("/Users/jim/Desktop/Work/temp/java1221/demo.txt"));
System.out.println(out3);
//4、FileOutputStream(File,boolean)创建字节流对象之前,File对象还可以执行File方法。创建字节输出流,如果参数2为true且文件存在则不会清空内容。如果文件不存在则创建文件。
FileOutputStream out4 = new FileOutputStream(new File("/Users/jim/Desktop/Work/temp/java1221/demo.txt"),true);
System.out.println(out4);
}
}
(3)功能方法(与OutputStream一致)
import java.io.*;
public class Demo3_FileOutputStream {
public static void main(String[] args) throws IOException {
OutputStream out = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
String s = "Hello World";
byte[] bytes = s.getBytes();
//write(byte[],int,int)
out.write(bytes,0,5);
out.flush();
out.close();
System.out.println("某部分某部分字节写入成功");
//结论:某部分某部分字节写,效率高,且代码少(较少使用)。
//method_一堆一堆字节写();
//method_一个一个字节写();
//method_构造方法();
}
private static void method_一堆一堆字节写() throws IOException {
OutputStream out = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
String s = "Hello World";
byte[] bytes = s.getBytes();
//write(byte[])
out.write(bytes);
out.flush();
out.close();
System.out.println("一堆一堆字节写入成功");
//结论:一堆一堆字节写,效率高,且代码少(建议使用)。
}
private static void method_一个一个字节写() throws IOException {
//功能方法
OutputStream out = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
byte b = 97;
//write(int)
/* FileNotFoundException 是 IOException 子类
IOException*/
out.write(b);//写入到文件中是'a'
//flush()
out.flush();
//close()
out.close();
System.out.println("一个一个字节写入成功");
//结论:一个一个字节写,效率低,且代码量大(不建议使用)。
}
}
3、InputStream类
(1)API介绍
(2)功能方法
4、FileInputStream类
(1)API介绍
(2)构造方法
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Demo4_FileInputStream {
public static void main(String[] args) throws FileNotFoundException {
/* 返回结果
FileNotFoundException 路径或文件不存在,出现该异常
*/
//FileINputStream(String)
FileInputStream in = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
System.out.println(in);//java.io.FileInputStream@610455d6
//FileInputStream(File) 获取字节输入流前,需要对路径的File对象执行操作时。
FileInputStream in2 = new FileInputStream(new File("/Users/jim/Desktop/Work/temp/java1221/demo.txt"));
System.out.println(in2);//java.io.FileInputStream@511d50c0
}
}
(3)功能方法(与InputStream功能一致)
import java.io.*;
public class Demo4_FileInputStream {
public static void main(String[] args) throws IOException {
//method_大文件读取();
//method_小文件读取操作();
//method_一个一个字节读();
//method_构造方法();
}
private static void method_大文件读取() throws IOException {
InputStream in = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
byte[] b = new byte[1024];
int len = -1;
while((len = in.read(b))!=-1){
//输出字符串
System.out.print(new String(b,0,len));//Hello
}
in.close();
System.out.println("一堆一堆字节读取成功");
//read(byte[],int,int)
//问题:针对读取中英混排文件,乱码(无法将原有数据表现出现,出现未知字符)问题。
//解决:字符输入流
}
private static void method_小文件读取操作() throws IOException {
InputStream in = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
//available() 获取文件总字节数
int available = in.available();
byte[] b = new byte[available];//缓冲区
int len = -1;//记录数据在缓冲区长度,如果结尾返回长度是-1
//read(byte[]) 读入缓冲区的总字节数,如果没有更多的数据,因为文件的结尾已经到达, -1 。
while((len = in.read(b))!=-1){
//输出字符串
System.out.println(new String(b,0,len));//Hello
}
in.close();
System.out.println("一堆一堆字节读取成功");
//结论:一堆一堆字节读,效率高,且代码量少(建议使用)。
//问题:使用.available()获取文件字节数,对于小文件可以加快读取效率,对于大文件(比内存还大文件),如内存8G,文件大小32G。
//解决:开辟一个1024倍数组来做缓冲区。
}
private static void method_一个一个字节读() throws IOException {
InputStream in = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
//read() 数据的下一个字节,如果达到文件的末尾, -1 。
int b = -1;
while ((b = in.read()) != -1) {
System.out.print((char) b);
}
System.out.println();
//close()
in.close();
System.out.println("一个一个字节读取成功");
//结论:一个一个字节读,效率低,且代码量大(不建议使用)。
}
}
5、使用字节流实现文件复制
(1)实现图示
(2)代码示例
import java.io.*;
public class Demo5_文件复制 {
public static void main(String[] args) {
//需求:将demo.txt复制到 /temp/下
InputStream in = null;
OutputStream out = null;
try {
//1、创建输入输出流
in = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
out = new FileOutputStream("/Users/jim/Desktop/Work/temp/demo.txt");
//2、读取数据到数组中
byte[] bs = new byte[1024];
int len = -1;
while ((len = in.read(bs)) != -1) {
//3、写入到数组中
out.write(bs, 0, len);
//4、刷新数组数据到硬盘中
out.flush();
}
System.out.println("文件复制成功...");
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5、BufferedOutputStream:字节输出缓冲流
(1)API介绍
(2)构造方法
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Demo6_BufferedOutputStream {
public static void main(String[] args) throws FileNotFoundException {
//构造方法
//BufferedOutputStream(OutputStream)
OutputStream os = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt",true);
BufferedOutputStream out = new BufferedOutputStream(os);
System.out.println(out);//java.io.BufferedOutputStream@610455d6
//注意
//1、如果在使用写入缓冲流时,保留原文件的内容,可以在构建写入流中假如参数true即可。
//2、缓冲流中的缓冲数组大小为8192
//BufferedOutputStream(OutputStream,int)
OutputStream os2 = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt",true);
BufferedOutputStream out2 = new BufferedOutputStream(os2,1024);
System.out.println(out2);//java.io.BufferedOutputStream@610455d6
}
}
(3)功能方法(与OutputStream类的功能一致)
import java.io.*;
public class Demo6_BufferedOutputStream {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt", true);
BufferedOutputStream out = new BufferedOutputStream(os);
String s = " World";
byte[] bytes = s.getBytes();
out.write(bytes);
out.flush();
out.close();
System.out.println("一堆一堆字节写入成功");
//method_构造方法();
}
}
6、BufferedInputStream类:字节输入缓冲流
(1)API介绍
解析:BufferedInputStream类是InputStream类子类,该类不提供输入流,需要构造时提供输入流对象,该类提供内部缓冲区数组。
(2)构造方法
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class Demo2_BufferedInputStream {
public static void main(String[] args) throws FileNotFoundException {
//构造方法
InputStream is = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
//BufferedInputStream(InputStream)
BufferedInputStream in = new BufferedInputStream(is);
System.out.println(in);//java.io.BufferedInputStream@610455d6
//BufferedInputStream(InputStream,int) 自定义缓冲区大小
BufferedInputStream in2 = new BufferedInputStream(is, 1024);
System.out.println(in2);//java.io.BufferedInputStream@511d50c0
}
}
(3)功能方法(与InputStream类的功能一致)
import java.io.*;
public class Demo2_BufferedInputStream {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt");
BufferedInputStream in = new BufferedInputStream(is);
int b = -1;
while ((b = in.read()) != -1) {
System.out.print((char) b);
}
is.close();
System.out.println("\n对缓冲区中的数据一个一个字节读取成功...");
//method_构造方法();
}
}
2、文件复制
import java.io.*;
public class Demo3_文件复制 {
public static void main(String[] args) {
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream("/Users/jim/Desktop/Work/temp/java1221/demo.txt"));
out = new BufferedOutputStream(new FileOutputStream("/Users/jim/Desktop/Work/temp/demo.txt"));
int b = -1;
while ((b = in.read()) != -1) {//将缓冲去的字节一个一个读取
out.write(b);//一个一个字节写入到缓冲区中
out.flush();
}
System.out.println("文件复制成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(in!=null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}