数据源
datasource。提供原始数据的原始媒介,常见的:数据库、文件、其他程序、内存、网络设备、IO设备等。
IO流以程序为中心
由数据源(文件、内存、数据库)流入程序中去为输入流;由程序流出到目的地(文件、内存、数据库)中为输出流。
核心类
1、File 文件类
2、InputStream 字节输入流
3、OutputStream 字节输出流
4、Rader 字符输入流
5、Writer 字符输出流
6、Closeable 关闭流接口
7、Flushable 强制刷新流接口
8、Serializable 序列化接口
IO流分类
节点流:可以直接从数据源或目的地读写数据。
处理流(包装流):不直接连接到数据源或目的地,对其他流进行封装,目的是简化操作和提高性能。
节点流和处理流的关系:
①、节点流处于IO流的一线,所有操作必须通过他们进行
②、处理流可以对其他流进行处理(提高效率或操作灵活性)
- 字节流:按照字节读取数据(InputStream、OutputStream)
- 字符流:按照字符读取数据(Reader、Writer),因为文件编码不同,从而有了对字符进行高效操作的字符流对象。
原理:底层还是基于字节流操作,自动搜寻了指定的码表。
IO流
节点流
四大抽象类
1、IntputStream:字节输入流
2、outPutStream:字节输出流
3、read:字符输入流
4、write:字符输出流
操作对象源文件存储在硬盘上,java对其操作需要借助操作系统OS,并且通知操作系统关闭资源
IO操作的四大步骤
1、创建源
2、选择流
3、操作(读/写)
4、释放资源
字节流
字节输入流:IntputStream
特性
1、字节输入流的父类
2、数据单位为字节(byte)
子类
1、FileInputStream
2、ByteArrayInputStream
FileInputStream:文件字节输入流
通过字节的方式读取文件,适合读取所有类型的文件(图像、音频)
基本方法
1、构造方法:newFileInputStream()
2、读取操作:read/read(byte[]b)
3、关闭资源,close()
/**
*案例:一
* FileIntputStream 文件字节输入流
* 1、创建源
* 2、选择流
* 3、读取操作:read():一个字节一个字节的读取,返回实际读取到的数据值
* 4、释放资源
*/
public class FileInputStreamTest {
public static void main(String[] args) {
//1、创建源
File src=new File("test.txt");
//2、选择流
InputStream is=null;
try {
is=new FileInputStream(src);
int temp=-1;
//3、读取操作
while ((temp=is.read())!=-1){
System.out.println((char) temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、释放资源
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*案例:二(字节数组方式读取)
* FileIntputStream 文件字节输入流
* 1、创建源
* 2、选择流
* 3、读取操作: read(byte[] b):从该输入流读取最多 b.length个字节的数据到字节数组中(缓冲区),返回实际读取到的数据的大小。
* 4、释放资源
*/
public class FileInputStreamTest02 {
public static void main(String[] args) {
//1、创建源
File src=new File("test.txt");
//2、选择流
InputStream is=null;
try {
is=new FileInputStream(src);
//3、读取操作(分段读取)
byte[]flush=new byte[1024];//缓冲容器
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
//字节数组-->字符串(解码)
String str=new String(flush,0,len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、释放资源
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayInputStream(字节数组输入流)
1、操作的数据在内存中,处理数据不要太大
2、资源释放不用通知操作系统OS,JAVA GC垃圾回收机制会自动处理
/**
* @auther TongFangPing
* @date 2019/9/26 13:47.
* ByteArrayIntputStream 字节数组输入流
* ByteArrayIntputStream和ByteArrayOutputStream。作用:用IO流的方式来完成对字节数组的读写
*原因:
* 流的来源或目的地并不一定是文件,也可以是内存中的一块空间,例如一个字节数组。
* java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream就是将字节数组当作流输入来源、
* 输出目的地的类。
* 如果在程序运行过程中产生过一些临时文件,就可以使用虚拟文件的方式来实现,不需要访问硬盘,而是直接访问内存。
* 提高了效率
* 1、创建源:字节数组,不要太大
* 2、选择流
* 3、读取操作: read(byte[] b):从该输入流读取最多 b.length个字节的数据到字节数组中(缓冲区),返回接收大小。
* 4、释放资源:可以不用处理:数据在内存当中,java垃圾回收机制会处理。
*/
public class ByteArrayInputStreamTest01 {
public static void main(String[] args) {
//1、创建源
byte[]src="talk is cheap show me the code".getBytes();
//2、选择流
InputStream is=null;
try {
is=new ByteArrayInputStream(src);
int temp;
//3、读取操作(分段读取)
byte[]flush=new byte[4];//缓冲容器,每次读取4个字节到缓冲区容器中去
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
//字节数组-->字符串(解码)
String str=new String(flush,0,len);
System.out.println(str);
}
}catch (IOException e) {
e.printStackTrace();
} finally {
//4、释放资源,可以不用处理,不用通知操作系统OS去释放资源。
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节输出流:outPutStream
特性
1、字节输出流的父类
2、数据单位为字节(byte)
子类
1、FileOutputStream
2、ByteArrayOutputStream
FileOutputStream
用于将数据写入到输出流File,适合所有类型的文件(图像、音频)
基本方法
1、构造方法:newFileOutputStream()
2、写入操作:Write()
3、刷新操作:flush()
4、关闭资源:close()
/**
* FileOutputStream 文件字节输出流
* * 1、创建源
* * 2、选择流
* * 3、写入操作:write():
* * 4、释放资源
*/
public class FileOutputStreamStudy01 {
public static void main(String[] args) {
//1、创建源
File file=new File("paji.txt");
OutputStream os=null;
try {
//2、选择流,非追加方式
os=new FileOutputStream(file);
//2、追加方式
//os=new FileOutputStream(file,true);
String msg="我是扒鸡我最棒!";
//字符-->字节(编码)
byte[] datas=msg.getBytes();
//3、写出操作
os.write(datas,0,datas.length);
//刷新此输出流并强制任何缓冲的输出字节被写出。
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4、释放资源
if(null!=os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayOutputStream(字节数组输出流)
1、不用关联File源文件
2、选择流,不使用多态
3、不用释放资源
方法:
toByteArray():创建一个新分配的字节数组。
/**
* ByteArrayOutputStream 字节数组输出流
* 该类实现了将数据写入字节数组的输出流。 不需要指定目的地,因为在内存中,无法指定具体的空间大小,所以内部构造了一个缓冲区,缓冲区会随着写入的字节数自动增长。 数据可以使用toByteArray()和toString()从缓冲区中获取
* * 1、创建源:内部维护
* * 2、选择流:不关联源
* * 3、写入操作:write():
* * 4、释放资源:可以不用处理
*/
public class ByteArrayOutputStreamStudy01 {
public static void main(String[] args) {
//1、创建源
byte[]dest=null;
//2、选择流(新增方法)
ByteArrayOutputStream baos=null;
try {
baos=new ByteArrayOutputStream();
String msg="我是扒鸡我最棒!";
//字符-->字节(编码)
byte[] datas=msg.getBytes();
//3、写出操作
baos.write(datas,0,datas.length);
//刷新此输出流并强制任何缓冲的输出字节被写出。
baos.flush();
//获取数据
dest=baos.toByteArray();//创建一个新分配的字节数组。
System.out.println(dest.length+"--->"+new String(dest,0,baos.size()));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4、释放资源,不用处理
if(null!=baos) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流
read:字符输入流
特性
1、字符输入流的父类
2、数据单位为字符
子类
FileRead:文件字符输入流,只适用于字符文件
FileRead:文件字符输入流
/**
* FileRead 文件字符输入流,只适用于字符文件
* 1、创建源
* 2、选择流
* 3、读取操作: read(byte[] b):从该输入流读取最多 b.length个字节的数据到字节数组中(缓冲区),返回大小。
* 4、释放资源
*/
public class FileReadTest01 {
public static void main(String[] args) {
//1、创建源
File src=new File("test.txt");
//2、选择流
Reader reader=null;
try {
reader=new FileReader(src);
int temp;
//3、读取操作(分段读取)
char[]flush=new char[1024];//缓冲容器
int len=-1; //接受长度
while ((len=reader.read(flush))!=-1){
//字符数组-->字符串
String str=new String(flush,0,len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、释放资源
try {
if(null!=reader) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
write:字符输出流
特性
1、字符输出流的父类
2、数据单位为字符(byte)
子类
FileWrite:文件字符输出流,通过字符的方式写入文本,仅适合字符文件
/**
* FileWrite 文件字符输出流,只适用于字符文件
* * 1、创建源
* * 2、选择流
* * 3、写入操作:write():
* * 4、释放资源
*/
public class FileWriteStudy01 {
public static void main(String[] args) {
//1、创建源
File file=new File("paji.txt");
Writer writer=null;
try {
//2、选择流,非追加方式
writer=new FileWriter(file);
//2、追加方式
//os=new FileOutputStream(file,true);
String msg="我是扒鸡我最棒!";
String msg2="我最棒";
char[] datas=msg.toCharArray();
//3、写入操作
writer.write(datas,0,datas.length);
//3、写入方式二,直接写入字符串
writer.write(msg2);
//3、写入方式三,append追加方式
writer.append("dasd").append("fsdfds").append("fsafds");
//刷新此输出流并强制任何缓冲的输出字节被写出。
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4、释放资源
if(null!=writer) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件拷贝Demo
/**
* 文件的拷贝:输入流、输出流的结合
*/
public class FileCopy {
public static void main(String[] args) {
long t1=System.currentTimeMillis();
copyFile("G:\\学习相关\\javaweb学习\\jsp视频\\12_EL 表达式 (隐式对象)__rec.avi","C:\\Users\\tfp12\\Desktop\\spp.avi");
long t2=System.currentTimeMillis();
System.out.println(t2-t1);
}
public static void copyFile(String srcPath,String destPath){
File src=new File(srcPath);
File copying=new File(destPath);
InputStream is=null;
OutputStream os=null;
try {
int len=-1;
byte[]flush=new byte[1024];
is=new FileInputStream(src);
os=new FileOutputStream(copying);
while ((len=is.read(flush))!=-1){
os.write(flush,0,len);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源,先打开的后关闭
if(null!=os){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}if (null!=is){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* @auther TongFangPing
* @date 2019/9/27 11:02.
* 文件(图片)的拷贝:
* 文件——>程序——>字节数组——>文件
*/
public class FileCopy02 {
public static void main(String[] args) throws IOException {
//图片转成字节数组
byte[]datas=fileToByteArray("super.jpg");
System.out.println(datas.length);
byteArrayToFile(datas,"super2.jpg");
// File f=new File("copysuper.jpg");
// f.delete();
}
/**
* 1、图片到字节数组:
* 1、图片到程序:FileInputStream
* 2、程序到字节数组:ByteArrayOutputStream
*/
public static byte[] fileToByteArray(String path) {
//创建源与目的地
File src = new File(path);
byte[] dest = null;
//选择流
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
is = new FileInputStream(src);
baos = new ByteArrayOutputStream();
//操作
byte[] flush = new byte[1024 * 10];
int len = -1;
while ((len = is.read(flush)) != -1) {
baos.write(flush, 0, len);
}
baos.flush();
return baos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 1、字节数组到文件
* 1、字节数组到程序:ByteArrayInputStream
* 2、程序到文件:FileOutputStream
*/
public static void byteArrayToFile(byte[]src,String filePath){
File dest=new File(filePath);
InputStream is=null;
OutputStream os=null;
is=new ByteArrayInputStream(src);
try {
os=new FileOutputStream(dest);
int len=-1;
byte[]flush=new byte[10];
while ((len=is.read(flush))!=-1){
os.write(flush,0,len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
自定义FileUtil工具类
/**
* @auther TongFangPing
* @date 2019/9/27 13:50.
* 封装拷贝
* 封装释放
*/
public class FileUtil {
public static void main(String[] args) {
//文件到文件
try {
InputStream is=new FileInputStream("paji.txt");
OutputStream os=new FileOutputStream("paji1号.txt");
copyFile(is,os);
} catch (IOException e) {
e.printStackTrace();
}
//文件到字节数组中
byte[]datas=null;
try {
InputStream is=new FileInputStream("super.jpg");
ByteArrayOutputStream os=new ByteArrayOutputStream();
copyFile(is,os);
datas=os.toByteArray();
System.out.println(datas.length);
} catch (IOException e) {
e.printStackTrace();
}
//字节数组到文件
try {
InputStream is=new ByteArrayInputStream(datas);
OutputStream os=new FileOutputStream("p-copy.png");
copyFile(is,os);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 对接输入输出流
* @param is
* @param os
*/
public static void copyFile(InputStream is,OutputStream os){
try {
int len=-1;
byte[]flush=new byte[1024];
while ((len=is.read(flush))!=-1){
os.write(flush,0,len);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源,先打开的后关闭
close(is,os);
}
}
/**
* 释放资源
* @param is
* @param os
*/
public static void close(InputStream is,OutputStream os){
if(null!=os){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}if (null!=is){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
try…with…resource方式
将输入输出流的声明部分放入try()中,删除finally部分代码
/**
* 资源的释放:try...with...resource
* 文件的拷贝:输入流、输出流的结合
*/
public class TryWithResource {
public static void main(String[] args) {
copyFile("H:\\迅雷下载\\BANDIZIP-SETUP.EXE","C:\\Users\\tfp12\\Desktop\\sp.exe");
}
public static void copyFile(String srcPath,String destPath){
File src=new File(srcPath);
File copying=new File(destPath);
// InputStream is=null;
// OutputStream os=null;
//资源释放,没有finally
try(InputStream is=new FileInputStream(src);
OutputStream os=new FileOutputStream(copying)) {
int len=-1;
byte[]flush=new byte[1024];
// is=new FileInputStream(src);
// os=new FileOutputStream(copying);
while ((len=is.read(flush))!=-1){
os.write(flush,0,len);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}