1.IO流概述
- IO流用来处理设备之间的数据传输
- Java对数据的操作是通过IO流的方式
- Java用于操作流的类都在IO包中
- 流按流向分为两种:输入流,输出流(数据是从内存到其他地方,还是从其他地方到内存)
流按操作类型分为两种:
* 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的 * 字符流 : 字符流只能操作纯字符数据,比较方便。
2.IO流常用父类
字节流的抽象父类:
* InputStream * OutputStream
字符流的抽象父类:
* Reader * Writer
3.IO程序书写
* 使用前,导入IO包中的类
* 使用时,进行IO异常处理
4.FileInputStream
a.概述:
* FileInputStream 从文件系统中的某个文件中获得输入字节。 * FileInputStream 用于读取诸如图像数据之类的原始字节流。 * 要读取字符流,请考虑使用 FileReader。
b.常见方法
* int read( ) 从此输入流中读取一个数据字节。 * read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
public class Temp1_FileInputStream {
//FileInputStream
public static void main(String[] args) throws IOException{
InputStream in = new FileInputStream("b.txt");
int a;
while((a=in.read())!=-1){
System.out.print((char)a);
}
in.close();
}
}
5.read()方法返回值为什么是int
* 因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111(-1)
6.FileOutputStream
- 常见方法
- void write(int b)
- void write(byte[] b)
- void write(byte[] b, int off, int len)
public class Demo10_FileOutputStream
{
public static void main(String[] args) throws IOException
{
/**
* 1. 如果指向的文件不存在则会帮忙创建
* 2. 直接往一个文件去写的时候,不会覆盖掉以前的所有的内容
*/
OutputStream out = new FileOutputStream("F:/test/abcd.txt",true);
out.write(98);
out.close();
}
}
7.拷贝图片
public class Temp3_copyImg {
//拷贝图片
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream("G:\\start.gif");
OutputStream outputStream = new FileOutputStream("F:\\start.gif");
int b = 0;
while((b=inputStream.read())!=-1){
outputStream.write(b);
}
inputStream.close();
outputStream.close();
}
}
8.拷贝大文件
public class temp4_copyBigFile {
//拷贝大文件
public static void main(String[] args) throws IOException{
InputStream in = new FileInputStream("D:\\QMDownload.rar");
OutputStream out = new FileOutputStream("F:\\test.rar");
System.out.println(in.available()); //输出文件的大小
byte[] bs = new byte[1024*1024*5];
int a = 0;
while((a = in.read(bs))!=-1){
out.write(bs, 0, a);
}
in.close();
out.close();
}
}
9.BufferedInputStream和BufferOutputStream拷贝
a.缓冲思想:
- 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
- 这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
b.BufferedInputStream
- BufferedInputStream内置了一个缓冲区(数组)
- 从BufferedInputStream中读取一个字节时
- BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个
- 程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
- 直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
- BufferedInputStream内置了一个缓冲区(数组)
c.拷贝的代码
public class Temp5_BufferedInputStream {
public static void main(String[] args) throws IOException{
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("b.txt"));
int n;
while((n=inputStream.read())!=-1){
outputStream.write(n);
}
outputStream.flush();
//outputStream.close();
inputStream.close();
}
}
10.小数组的读写和带Buffered的读取哪个更快?
* 定义小数组如果是8192个字节大小和Buffered比较的话
* 定义小数组会略胜一筹,因为读和写操作的是同一个数组
* 而Buffered操作的是两个数组
public class Temp6_speed {
public static void main(String[] args) throws IOException{
InputStream in = new FileInputStream("F:\\339\\CoolShow_01.mp4");
OutputStream out = new FileOutputStream("F:\\test.mp4");
BufferedInputStream inBuffer = new BufferedInputStream(new FileInputStream("F:\\339\\CoolShow_01.mp4"));
BufferedOutputStream outBuffer = new BufferedOutputStream(new FileOutputStream("F:\\test2.mp4"));
long start = System.currentTimeMillis();
byte[] bs = new byte[8192];
int a = 0;
while((a = in.read(bs))!=-1){
out.write(bs, 0, a);
}
System.out.println("FileInputStream:"+(System.currentTimeMillis()-start)+"ms");
in.close();
out.close();
long start2 = System.currentTimeMillis();
int b = 0;
while((b=inBuffer.read())!=-1){
outBuffer.write(b);
}
System.out.println("BufferedInputStream:"+(System.currentTimeMillis()-start2)+"ms");
inBuffer.close();
outBuffer.close();
}
}
11.flush和close方法的区别
flush()方法
* 用来刷新缓冲区的,刷新后可以再次写出
close()方法
* 用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出
12.字节流读写中文
- 字节流读取中文的问题
- 字节流在读中文的时候有可能会读到半个中文,造成乱码
- 字节流写出中文的问题
- 字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组
- 写出回车换行 write(“\r\n”.getBytes());
public class Temp7_luanma {
public static void main(String[] args) throws IOException{
InputStream inputStream= new FileInputStream("zhongwen.txt");
OutputStream outputStream = new FileOutputStream("zhongwen.txt");
//写
outputStream.write("无聊是最痛苦的事".getBytes());
//读
byte[] css = new byte[2];
int a = 0;
while((a=inputStream.read(css))!=-1){
System.out.print(new String(css));
}
outputStream.close();
inputStream.close();
}
}
13.流的标准处理异常代码
- a.1.6版本及其以前
* try finally嵌套
public class Temp8_Exception1 {
public static void main(String[] args) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream("a.txt");
out = new FileOutputStream("b.txt");
int b;
while((b=in.read())!=-1){
out.write(b);
}
}finally{
try {
if(in != null)
in.close();
}finally{
if(out != null)
out.close();
}
}
}
}
b.1.7版本
* 在try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,在try后面的{}(读写代码)执行后就会自动调用,流对象的close方法将流关掉
public class Demo16_try implements AutoCloseable
{
public static void main(String[] args) throws Exception
{
try(
//该处写的代码只能是IO流的对象的定义
FileOutputStream fos = new FileOutputStream("bbb.txt");
FileInputStream fis = new FileInputStream("aaa.txt");
Demo16_try cc= new Demo16_try();
)
{
//正在读写文件的代码
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
}
}
@Override
public void close() throws Exception
{
System.out.println("cccc");
}
}
14.图片加密
public class Demo17_Image
{
public static void main(String[] args) throws Exception
{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c.jpg"));
BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream("c.jpg"));
BufferedOutputStream bos2= new BufferedOutputStream(new FileOutputStream("b.jpg"));
//加密
int b;
while((b = bis.read()) != -1) {
bos.write(b ^ 123);
}
//解密
while((b = bis2.read()) != -1) {
bos2.write(b ^ 123);
}
bis.close();
bos.close();
bis2.close();
bos2.close();
}
}
15.在控制台录入文件的路径,将文件拷贝到当前项目下
16.将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
public class Temp18 {
//将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
public static void main(String[] args) throws IOException{
Scanner inScanner = new Scanner(System.in);
OutputStream out = new FileOutputStream("temp18.txt");
while(true){
String str = inScanner.nextLine();
if("quit".equals(str)){
break;
}
byte[] cs = str.getBytes();
out.write(cs);
out.write("\r\n".getBytes());
}
out.close();
}
}