开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情
IOStream
概述
IO 输入输出流:输入/输出流
- Input:输入
- Output:输出
引入:File 类只能操作文件对象本身,不能读写文件对象的内容,读写数据内容,应该使用 IO 流
IO 流是一个水流模型:IO 理解成水管,把数据理解成水流
IO 流的分类:
-
按照流的方向分为:输入流,输出流。
- 输出流:以内存为基准,把内存中的数据写出到磁盘文件或者网络介质中去的流称为输出流
- 输入流:以内存为基准,把磁盘文件中的数据或者网络中的数据读入到内存中的流称为输入流
-
按照流的内容分为:字节流,字符流
- 字节流:流中的数据的最小单位是一个一个的字节,这个流就是字节流
- 字符流:流中的数据的最小单位是一个一个的字符,这个流就是字符流(针对于文本内容)
流大体分为四大类:字节输入流、字节输出流、字符输入流、字符输出流
字节流
字节输入
FileInputStream 文件字节输入流:以内存为基准,把磁盘文件中的数据按照字节的形式读入到内存中的流
构造方法:
public FileInputStream(File path):创建一个字节输入流管道与源文件对象接通public FileInputStream(String pathName):创建一个字节输入流管道与文件路径对接,底层实质上创建 File 对象
方法:
public int read():每次读取一个字节返回,读取完毕会返回 -1public int read(byte[] buffer):从字节输入流中读取字节到字节数组中去,返回读取的字节数量,没有字节可读返回 -1,byte 中新读取的数据默认是覆盖原数据,构造 String 需要设定长度public String(byte[] bytes,int offset,int length):构造新的 Stringpublic long transferTo(OutputStream out):从输入流中读取所有字节,并按读取的顺序,将字节写入给定的输出流
public class FileInputStreamDemo01 {
public static void main(String[] args) throws Exception {
// 1.创建文件对象定位dlei01.txt
File file = new File("Demo/src/dlei01.txt");
// 2.创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream(file);
// 3.读取一个字节的编号返回,读取完毕返回-1
//int code1 = is.read(); // 读取一滴水,一个字节
//System.out.println((char)code1);
// 4.使用while读取字节数
// 定义一个整数变量存储字节
int ch = 0 ;
while((ch = is.read())!= -1){
System.out.print((char) ch);
}
}
}
一个一个字节读取英文和数字没有问题,但是读取中文输出无法避免乱码,因为会截断中文的字节。一个一个字节的读取数据,性能也较差,所以禁止使用上面的方案
采取下面的方案:
public static void main(String[] args) throws Exception {
//简化写法,底层实质上创建了File对象
InputStream is = new FileInputStream("demo/src/test.txt");
byte[] buffer = new byte[3];//开发中使用byte[1024]
int len;
while((len = is.read(buffer)) !=-1){
// 读取了多少就倒出多少!
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
}
File f = new File("demo/src/test.txt");
InputStream is = new FileInputStream(f);
// 读取全部的
byte[] buffer = is.readAllBytes();
String rs = new String(buffer);
System.out.println(rs);
字节输出
FileOutputStream 文件字节输出流:以内存为基准,把内存中的数据,按照字节的形式写出到磁盘文件中去
构造方法:
public FileOutputStream(File file):创建一个字节输出流管道通向目标文件对象public FileOutputStream(String file):创建一个字节输出流管道通向目标文件路径public FileOutputStream(File file, boolean append): 创建一个追加数据的字节输出流管道到目标文件对象public FileOutputStream(String file, boolean append): 创建一个追加数据的字节输出流管道通向目标文件路径
API:
-
public void write(int a):写一个字节出去 -
public void write(byte[] buffer):写一个字节数组出去 -
public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去,从 pos 位置,写出 len 长度 -
FileOutputStream 字节输出流每次启动写数据的时候都会先清空之前的全部数据,重新写入:
OutputStream os = new FileOutputStream("demo/out05"):覆盖数据管道OutputStream os = new FileOutputStream("demno/out05" , true):追加数据的管道
说明:
- 字节输出流只能写字节出去,字节输出流默认是覆盖数据管道
- 换行用:os.write("\r\n".getBytes())
- 关闭和刷新:刷新流可以继续使用,关闭包含刷新数据但是流就不能使用了
OutputStream os = new FileOutputStream("demo/out05");
os.write(97);//a
os.write('b');
os.write("\r\n".getBytes());
os.write("学习Java".getBytes());
os.close();
文件复制
字节是计算机中一切文件的组成,所以字节流适合做一切文件的复制
public class CopyDemo01 {
public static void main(String[] args) {
InputStream is = null ;
OutputStream os = null ;
try{
//(1)创建一个字节输入流管道与源文件接通。
is = new FileInputStream("D:\test\tupian\test.jpg");
//(2)创建一个字节输出流与目标文件接通。
os = new FileOutputStream("D:\test\test.jpg");
//(3)创建一个字节数组作为桶
byte buffer = new byte[1024];
//(4)从字节输入流管道中读取数据,写出到字节输出流管道即可
int len = 0;
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("复制完成!");
}catch (Exception e){
e.printStackTrace();
} finally {
/**(5)关闭资源! */
try{
if(os!=null)os.close();
if(is!=null)is.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}