图床
流的分类
- 按流向分类:
- 输入流:数据源到程序(InputStream、Reader读进来)
- 输出流:程序到目的地(OutStream、Writer写出去)
- 按功能分类:(是否直接操作数据源)
-
节点流:可以直接从数据源或目的地中读写数据
-
处理流(包装流):不直接连接到数据源和目的地,是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
注:节点流是处于io操作的第一线,所有操作必须通过他来进行。
- 按照数据分类
-
字节流:按照字节读取数据(InputStream、OutputStream)
-
字符流:按照字符读取数据(Reader、Writer)
注:操作字符:即我们可以看懂的纯文本,汉语、英语。由于要让计算机认识,所以字符流的底层还是基于字节流的操作(自动的在码表中进行转换)。
IO节点流
- 字节流:按照字节读取数据(音频、视频、word、excel)inputStream、outputStream
- 字符流:按照字符读取数据(处理的数据为文本,字符时)Reader、Writer
注:能使用字符流的地方一定可以使用字节流处理,但是可以使用字节流的地方不一定可以使用字符流来处理。
要知道的:
- 在计算机里面的文件是存储在硬盘上,Java虽然需要和文件打交道,但是它是不可以直接对硬盘进行操作,而是通过虚拟机和我们的操作系统进行交互(向操作系统进行申请),所以File代表的是Java和文件的一种联系.。
- java虚拟机无权调用垃圾回收机制,只能通知操作系统可以释放资源了
四大抽象类
这四个类属于抽象流类,不能在程序中直接实例化使用,可以使用其派生的类。
- InputStream:字节输入流的父类,数据单位为字节
//从输入流读取数据的下一个字节。
abstract int read()
//从输入流读取一些字节数,并将它们存储到缓冲区 b 。(返回的读取的字节数)
int read(byte[] b)
//关闭此输入流并释放与流相关联的任何系统资源。
void close()
-
OutputStream:字节输出流的父类,数据单位为字节
注:在我们操作IO的时候内部会有一个类似于缓冲器,当这个缓冲器达到一定数值才会将里面的数据缓冲出去,如果没有达到指定数值,则缓冲器里面的数据则会驻留在内存中;此时为了避免数据能够缓冲出去,需要强制刷新flush或者关闭资源也会强制刷新。
//写入字符数组的一部分。
void write(char[] cbuf, int off, int len)
//写一个字符
void write(int c)
//写一个字符串的一部分。
void write(String str, int off, int len)
//刷新流。
void flush()
//关闭流,先刷新。
void close()
- Reader:字符输入流的父类,数据单位为字符
//读一个字符
int read()
//将字符读入数组。
int read(char[] cbuf)
//关闭流并释放与之相关联的任何系统资源。
abstract void close()
- Writer:字符输出流的父类,数据单位为字符
//写入一个字符数组。
void write(char[] cbuf)
//写入字符数组的一部分。
abstract void write(char[] cbuf, int off, int len)
//写一个字符
void write(int c)
//写一个字符串
void write(String str)
//写一个字符串的一部分。
void write(String str, int off, int len)
//刷新流。
abstract void flush()
//关闭流,先刷新。
abstract void close()
相关方法详解
你要知道的:在Java7中,InputStream被定义为一个抽象类,相应的,该类下的read()方法也是一个抽象方法,这也就意味着必须有一个类继承InputStream并且实现这个read方法。 可以看出下面在这三个方法中,只有参数列表为空的read方法定义为抽象方法,这也就意味着在直接继承自InputStream的所有子类中,必须重写这个方法.
//从输入流读取数据的下一个字节。
abstract int read()
//从输入流读取一些字节数,并将它们存储到缓冲区 b 。
int read(byte[] b)
//从输入流读取最多len字节的数据到一个字节数组。
int read(byte[] b, int off, int len)
/**
*方法详解:
* (1)从输入流读取数据的下一个字节。 值字节被返回作为int范围0至255 。
* (2)如果没有字节可用,因为已经到达流的末尾,则返回值-1 ;该方法阻塞直到输入数据可用,检测到流的结尾,或抛* * 出异常。
* (3)一个子类必须提供这个方法的一个实现。
* (4)返回的结果:数据的下一个字节,如果达到流的末尾, -1 。
*/
public abstract int read()throws IOException
通俗大白话版本:
注1:这个方法的返回值是int类型.
注2:这个方法每次从数据源中读取一个byte并返回
要知道的:一个byte表示8个二进制位,那么这8个二进制位就是一个0-255之间的十进制数字,实际上在Java中,byte就是一个0-255之间的整数,而将从文件中读取的二进制转化成十进制这一过程是由read()方法完成的。 也就是说,read()这个方法完成的事情就是从数据源中读取8个二进制位,并将这8个0或1转换成十进制的整数,然后将其返回。
/*
* (1)从输入流读取一些字节数,并将它们存储到缓冲区b 。 实际读取的字节数作为整数返回。(返回值为23则说明读取* 了23个字节)
* (2)该方法阻塞直到输入数据可用,检测到文件结束或抛出异常。
* (3)如果b的长度为零,则不会读取字节并返回0 ; 否则,尝试读取至少一个字节。 如果没有字节可用,因为流在文件 * 末尾,则返回值-1 ; 否则,读取至少一个字节并存储到b 。
*
* 第一个字节读取存储在元素b[0] ,下一个字节存入b[1]等等。 读取的字节数最多等于b的长度。 令k为实际读取的字* 节数; 这些字节将存储在元素b[0]至b[ k -1] ,使元素b[ k ]至b[b.length-1]不受影响。
* 该read(b)用于类方法InputStream具有相同的效果为:
* 方法1:read(b, 0, b.length)
* 方法2:read(b,0,k)
*/
public int read(byte[] b)
throws IOException
通俗大白话版本
注1:这个方法使用一个byte的数组作为一个缓冲区,每次从数据源中读取和缓冲区大小(二进制位)相同的数据并将其存在缓冲区中。读取的字节数最多等于数组的个数当然byte数组中存放的仍然是0-255的整数,(将二进制转换为十进制这个过程仍然是read方法实现的。 )
注2:虽然我们可以指定缓冲区的大小,但是read方法在读取数据的时候仍然是按照字节来读取的。在utf-8等变长编码中,一个复杂字符(比如汉字)所占字节往往大于1,并且长度往往是不固定的。(参照UTF-8编码规则)按照字节读取数据会将字符割裂,这就导致我们在使用read(byte[] b)方法读取文件时,虽然指定了缓冲区的大小,但是仍然会出现乱码。
IO标准步骤
- 创建源(选择要搬家的房子)
- 选择流(选择搬家公司)
- 具体操作(选择搬家方式)
- 释放资源(打发搬家公司走人)
实战1:字节数据的读取FileInputStream
/**非标准版
* 1.创建源
* 2.选择流(字节输入流:InputStream)
* 3.操作
* 4.释放
* @描述:按照每个字节的进行读取(低级版不推荐使用)
*/
public class demon {
public static void main(String[] args) {
//1.创建源
File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
//2.选择流(文件字节输入流)
try {
InputStream in = new FileInputStream(file);
//3.操作(读取数据)
int d1 = in.read();//返回的字节的值是一个0~255之间的整数
int d2 = in.read();
int d3 = in.read();
System.out.println((char)d1);
System.out.println((char)d2);
System.out.println((char)d3);
//4.关闭资源
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实战1_1:字节数据的读取FileInputStream
//标准版
/**
* 1.创建源
* 2.选择流(字节输入流:InputStream)
* 3.操作(读数据)
* 4.关闭资源
* @描述:按照每个字节的进行读取(标准版)
* 操作工具:标尺
*/
public class IoTest02 {
public static void main(String[] args) {
//1.创建源
File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
//2.选择流(文件字节输入流)
InputStream in = null;
try {
in = new FileInputStream(file);
//3.操作(读取数据):操作之前需要判断源文件是否有字节可读
int temp;//标尺
try {
while((temp = in.read())!=-1){
System.out.println((char)temp);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
//4.关闭资源
try {
if(in != null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实战练习2:按照指定字节数组的形式进行数据的读取
/**
* 1.创建源
* 2.选择流(字节输入流:InputStream)
* 3.操作(读取数据)
* 4.关闭
* @描述:将数据按照字节数组的形式进行读取(升级版推荐使用)
* 操作工具:小车(byte[])、标尺
*/
public class IoTest03 {
public static void main(String[] args) {
//1.创建源
File file = new File("E:/Java workspace/gui_gu/src2/com/sxt/IO/test.txt");
//2.选择流(文件字节输入流)
InputStream in = null;
try {
in = new FileInputStream(file);
//3.操作(读取数据)
//3.1缓冲容器(以指定字节数的形式存放进去)(准备小车和标尺)
byte[] flush = new byte[3];//小车:将读取的数据存放在这里面
int len = -1;//标尺:用来判断是否还有数据可读
try {
//3.2开始读取数据并装进刚才准备好的小车中(flush字节数组)
while((len = in.read(flush)) != -1){
//字节数组-->字符串(解码)(将小车中的数据进行包装并显示)
String str = new String(flush,0,len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(in != null){
try {
//4.关闭
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileInputStream
定义:通过字节的方式读取文件,可以读取任意类型的文件。(图片、视频等);如果是全字符读取可以考虑FileReader
FileOutputStream
定义:通过字节的方式写出或追加数据到文件,适合所有类型的文件(图片、视频等);如果是全字符可以考虑FileWriter
实战练习3:通过字节的方式写出或追加数据到文件
/**
* 1、创建源
* 2、选择流(字节输出流:OutputStream)
* 3、操作(写出)
* 4、关闭
* @描述:以字节的方式写出数据到文件
* 操作工具:小车(byte[])、要写出的数据
*/
public class OutTest {
public static void main(String[] args) {
//1、创建源(如果源文件不存在则会自动创建)
File dest = new File("destination.txt");
OutputStream out = null;
try {
//2、选择流(文件字节输出流)
//out = new FileOutputStream(dest,true);追加写入
out = new FileOutputStream(dest);
//3.操作(写出)
//3.1准备要写出的数据,并放进一个字节数组中
String str = "Believes Yourself!";//准备数据
byte[] b = str.getBytes();//将数据放进小车中
try {
//3.2:开始写出输入(将装满数据的小车写出)
out.write(b);
//3.3为了防止数据驻留在内存,每次写出后可以flash一下哦
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
//关闭
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实战1_3:字节数据的拷贝
package com.sxt.IO;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Copy {
/**
* 1、创建数据源头和目的源
* 2、选择流:字节输入流和输出流(InputStream、OutputStream)
* 3、操作:读取操作和写出操作
* 4、关闭:先打开的后关闭
* 操作工具:小车(byte[])、标尺
*@描述:通过文件输入流和文件输出流完成文件的复制操作
* @param args
*/
public static void main(String[] args) {
File src = new File("src.txt");
File des = new File("des.txt");
copy(src,des);
}
public static void copy(File src,File des){
//2.1、选择输入流
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
//2.2、选择输入流
out = new FileOutputStream(des);
//3.1、文件的读取操作(准备小车和标尺)
int tem;//标尺:判断是否还有可读的数据
byte[] flush = new byte[1024];//小车:用来存放读取的数据
try {
//3.2、文件的读取操作(将数据进行读取操作并放进小车中)
while((tem = in.read(flush))!=-1){
//3.3、文件的写出操作(将装满数据从小车进行写出操作)
out.write(flush,0,tem);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(out != null){
try {
//4.1、关闭资源
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in != null){
try {
//4.2、关闭资源
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实战2: 字符数据的读取FileReader
package com.sxt.IO;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
/**
* 1.创建源
* 2.选择流(字符输入流:Reader)
* 3.操作
* 4.释放
* @描述:通过字符输入流来完成数据的读取
* 操作工具;标尺、小车(char[])
*/
public class ReaderTest {
public static void main(String[] args) {
//1.创建源
File file = new File("hello.txt");
//2.选择流
Reader reader = null;
try {
reader = new FileReader(file);
//3.读取数据(操作):当读取的数据不存在时返回-1
int len;//标尺
char[] flush = new char[1024];//小车
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(reader != null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实战练习6:通过使用字符输出流里来进行数据的写出
package com.sxt.IO;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* 1.准备源
* 2.选择流(字符输出流:Writer)
* 3.写出操作
* 4.关闭
* @描述:通过字符输出流完成数据的写出
* 操作工具:小车(char[])、要写出的数据
*/
public class WriterTest {
public static void main(String[] args) {
//1.准备源
File des = new File("des.txt");
//2.选择字符输出流
Writer writer = null;
try {
writer = new FileWriter(des);
} catch (IOException e) {
e.printStackTrace();
}
//3.读取操作
//3.1准备要写出的数据
String data = "我能行!加油!";
//3.2准备小车
char[] flush = new char[1024];
//3.3将数据放进小车中
flush = data.toCharArray();
try {
//3.3读取操作
writer.write(flush);
//3.4flush操作
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(writer != null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实战2_1:字符数据的写出FileWriter
package com.sxt.IO;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
/**
* 1.创建源
* 2.选择流(字符输出流)
* 3.操作
* 4.释放
* @描述:按照每个字节的进行读取
* 和字节输出流的差别:选择流的不同、小车的类型不同
*/
public class ReaderTest {
public static void main(String[] args) {
//创建源
File file = new File("hello.txt");
//选择流
Reader reader = null;
try {
reader = new FileReader(file);
//读取数据(操作):当读取的数据不存在时返回-1
int len;
char[] flush = new char[1024];
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{
//关闭资源
try {
if(reader != null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实战2-2:字符数据的拷贝
package com.sxt.IO;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/**
* 1.准备源(数据源和目的源)
* 2.选择流(字符输入流和字符输出流:Reader、Writer)
* 3.操作
* 4.关闭(先打开的后关闭)
* @描述:通过字符输出流和字符输入流来完成文件的复制
* 操作工具:小车(char[])、标尺
*/
public class Copy_read_writer {
public static void main(String[] args) {
//1.准备源
File src = new File("src.txt");
File des = new File("des.txt");
//2.选择流
Reader reader = null;
Writer writer = null;
try {
reader = new FileReader(src);
writer = new FileWriter(des);
//3.操作
//3.1准备小车
char[] flush = new char[1024];
//3.2准备标尺
int len;
//3.3读取数据并装进小车
while((len = reader.read(flush))!= -1){
//3.4将装满数据的小车进行写出操作
writer.write(flush);
//3.4flush操作
writer.flush();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//4.关闭
if(writer != null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实战总结
- 以上处理的流都有一个共同特点:即源头都是文件(FileInputStream、FileOutputStream)
- 源头处于硬盘上,而JVM是无法直接访问硬盘上的资源,必须借助操作系统;因此操作完成后要释放资源
字节数组引入:
- 此时将源头换成内存(字节数组),可以看成是电脑上的一块内存、网络上的一块内存、远程服务器上的一块内存
- JVM可以直接访问内存,因此使用的资源是有垃圾回收器进行时放,因此不用我们手动关闭
字节数组流
要知道的:
- 所有的东西都可以转换成字节数组(例如:字符串、对象、...);
- 由于字节数组是二进制形式因而更方便进行网络的传输。
- 字节数组的大小不要设置太大
主要区别:
- 创建的源都是:字节数组
- 不需要关闭流
字节数组输入流ByteArrayInputStream
package com.sxt.IO;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 1.创建源:(byte[])“不同点1”
* 2.选择流(字节输入流:InputStream)
* 3.操作
* 4.关闭:可以省略 “不同点2”
* @描述:字节数组输入流
* 操作工具:标尺、小车(byte[])
*特点:选择流的不同、小车是byte[]、不需要关闭流
*/
public class ByteArrayIo {
public static void main(String[] args) {
//1.创建源
byte[] src = "Talk is cheap , Just show me your code!".getBytes();
//2.选择流
InputStream in = new ByteArrayInputStream(src);
//3.操作
//3.1标尺
int len;
//3.2小车
byte[] flush = new byte[2];
try {
while((len = in.read(flush)) != -1){
//打包输出:字节数组-->字符串(解码)
String s = new String(flush,0,len);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节数组输出流ByteArrayOutputStream
package com.sxt.IO;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* 1.创建源:源头内部来维护(不需要目的源文件) “不同点1”
* 2.选择流:ByteArrayOutputStream(不关联源即由于使用的是子类新增的方法因此不能使用多态) “不同点2”
* 3.操作:写出内容 “不同点3”
* 3.1获取数据:byteArrayIO.toByteArray();
* 4.关闭:可以省略 “不同点4”
* @描述:字节数组输出流
* 操作工具:小车、要写出的数据
*/
public class ByteArrayIo_writer {
public static void main(String[] args) {
//1.创建源
byte[] dest = null;
//2.选择流
ByteArrayOutputStream byteArrayIO = new ByteArrayOutputStream();
//3.操作
//3.1准备工具
String s = "Show me your code!";//数据
byte[] flush = s.getBytes();//小车
//3.2数据的写出
try {
byteArrayIO.write(flush);
//3.3 flush操作
byteArrayIO.flush();
//3.4获取数据
dest = byteArrayIO.toByteArray();
System.out.println(dest.length+"---->"+
new String(dest,0,byteArrayIO.size()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
对接流
package io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 1、图片---字节数组
* 1.1、图片--程序
* 1.2、程序--字节数组
* 2、字节数组---图片
* 2.1、字节数组--程序
* 2.1、程序--图片
* @描述:对接流
*/
public class ComprehensiveIO {
public static void main(String[] args) {
//1、图片--字节数组
byte[] src = fileToByteArray("src/images/p1.jpg");
//2、字节数组--图片
byteArrayToFile(src,"src/images/copy_p1.jpg");
}
/**
* 过程:图片(文件)--程序--字节数组
*@描述:将图片转换成字节数组的形式
* @param 图片被转换成的字节数组
* @return
*/
private static byte[] fileToByteArray(String path) {
//FileInPutStream ---> byteArrayOutputStream
//1、创建源
File srcFile = new File(path);
byte[] desFile = null;
//2、选择流
InputStream in = null;
try {
in = new FileInputStream(srcFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
//3、数据的读取
int len;
byte[] flush = new byte[1024];
try {
while((len = in.read(flush))!= -1){
//3.1、整理数据并输出(注意这里write写出的范围是“0--len”)
out.write(flush,0,len);
out.flush();
desFile = out.toByteArray();
}
return desFile;
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}return null;
}
/**
* 过程:字节数组--程序--图片(文件)
*@描述:将字节数组中的图片(byte类型)还原成图片(.jpg)的形式
* @param src 要还原的源文件
* @param string 还原后要保存的图片
*/
private static void byteArrayToFile(byte[] src, String path) {
//byteArrayInputStream --> FileOutputStream
//1、创建目的源
File file = new File(path);
//2、选择流
InputStream in = null;
OutputStream out = null;
in = new ByteArrayInputStream(src);
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
//3、对数据进行操作
int len;
byte[] flush = new byte[1024];
try {
while((len=in.read(flush))!= -1){
out.write(flush,0,len);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
综合应用:工具类的使用
引入:由上面的学习可以知道抽象类:InputStream、OutputStream下的具体实现类的存储数据的方式都是样的:标尺、小车、判断是否有数据可读、数据的写出操作;因此这些都可以封装成一个方法便于代码的管理。
- InptuStream抽象类下主要的具体实现类:FileInputStream、ByteArrayInputStream
- OutputStream抽象类下的主要的具体实现类:FileOutputStream、ByteArrayOutputStream
package com.sxt.IO;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
/**
* 1、字节数据的封装拷贝
* 2、封装释放资源
* 3、try ... with ... resource
*@描述:
* @param args
*/
public static void main(String[] args) {
//1.1、字节文件与字节文件之间的拷贝
try {
InputStream in = new FileInputStream("src2/com/sxt/IO/test.txt");
OutputStream out = new FileOutputStream("src2/com/sxt/IO/test_copy.txt");
copy(in,out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//1.2、字节文件到字节数组之间的拷贝
byte[] datas = null;
try {
InputStream in = new FileInputStream("src2/com/sxt/IO/images/p1.jpg");
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in,out);
datas = out.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//1.3、字节数组到字节文件的拷贝
try {
InputStream in = new ByteArrayInputStream(datas);
OutputStream out = new FileOutputStream("src2/com/sxt/IO/images/p1_copy.jpg");
copy(in,out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void copy(InputStream in,OutputStream out){
try {
//3.1、文件的读取操作
int tem;
byte[] flush = new byte[1024];
try {
while((tem = in.read(flush))!=-1){
//3.2、文件的写出操作
out.write(flush,0,tem);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
} finally{
//资源的释放(close)
close(in, out);
}
}
//2、输入流和输出流资源的释放
public static void close(InputStream in , OutputStream out){
if(out != null){
try {
//4.1、关闭资源
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in != null){
try {
//4.2、关闭资源
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//2.2升级版:多个资源的释放(因为在输入流和输出流的实现类中都有closeable接口)
public static void close(Closeable...clos){
for(Closeable io : clos){
try {
io.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
处理流
引入1_模拟方法器对人的声音的放大
package com.sxt.IO_01;
public class Decorate {
/**
*@描述:
* @param args
*/
public static void main(String[] args) {
Person p = new Person();
p.say();
Amplify amplify = new Amplify(p);
amplify.say();
}
}
/**
*
* @描述:定义接口
*/
interface Say{
void say();
}
/**
*
* @描述:定义人并实现承接口
*/
class Person implements Say{
int voice = 10;
@Override
public void say() {
System.out.println("原来声音大小为:"+this.voice);
}
}
/**
*
* @描述:定义放大器并继承接口对声音进行放大
*/
class Amplify implements Say{
private Person p;
public Amplify(Person p) {
this.p = p;
}
@Override
public void say() {
System.out.println("放大后的声音为:"+p.voice * 1000);
}
}