------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
字节流
一.IO流
1.概念
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的类都在IO包中
流按流向分为两种:输入流,输出流。
流按操作类型分为两种:字节流与字符流。 字节流可以操作任何数据(所有的数据在电脑上都是以字节的形式存储的),字符流只能操作纯字符数据,比较方便。
2.IO流常用父类
字节流的抽象父类:
InputStream ,OutputStream
字符流的抽象父类:
Reader , Writer
3.IO程序书写
使用前,导入IO包中的类
使用时,进行IO异常处理
使用后,释放资源
二.字节流
1.读取文件
创建FileInputStream对象, 指定一个文件. 文件必须存在, 不存在则会抛出FileNotFoundException
使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1
读取结束后需要释放资源, 调用close()方法关闭输入流
2.写出文件
创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.
使用write()方法可以向文件写出一个字节.
写出结束后同样需要调用close()
3.拷贝文件
可以从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低
我们可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出1byte = 8bit
4.常用方法
InputStream:
read() 读取一个字节
read()方法每次读到的是一个字节,为什么返回是int而不是byte
因为字节流可以读取任意类型的文件,比如音频视频图片等,如果读一个字节返回是byte类型的,在读过程中很有可能会读到-1
如果读到byte类型的-1,返回也是byte类型的,那么循环就会结束,剩下的数据读不出来,那么如果返回是int类型的,读到byte
类型的-1,会在前面补上24个0,-1变成的255,程序不会结束,只有读到了文件的结束标记才会结束,这样做不会丢失数据
1 0000001 原码
1 1111110
1 1111111 补码
00000000 00000000 00000000 11111111 把byte变成int
文件结束标记的-1是一个int类型
read(byte[]) 读取若干(数组长度)字节
available() 获取可读的字节数
close() 关闭流, 释放资源
OutputStream:
write(int) 写出一个字节
write(byte[]) 写出数组中的所有字节
write(byte[],start,len);
close() 关闭流, 释放资源
5.BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组)
从BufferedInputStream中读取一个字节时
BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个
程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
6.BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组)
程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中
直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里
实例:
逐个字符拷贝的实例:效率非常的低
<span style="font-size:18px;">package cn.itcast.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3_Copy {
/**
* @param args
* 拷贝文件
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//demo1();
FileInputStream fis = new FileInputStream("光明.mp3");
FileOutputStream fos = new FileOutputStream("copy.mp3");
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
fis.close();
fos.close();
}</span>
定义一个字节数组的复制:字节数组一般定义为[1024*8]
<span style="font-size:18px;">package cn.itcast.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3_Copy {
/**
* @param args
* 拷贝文件
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//demo1();
FileInputStream fis = new FileInputStream("光明.mp3");
FileOutputStream fos = new FileOutputStream("copy.mp3");
byte[] buf = new byte[1024*8];
int len;
while((len = fis.read(buf)) != -1) {
fos.write(buf,0,len);
}
fis.close();
fos.close();
}</span>
建立一个与文件大小相同的字节数组:不建议使用,如果文件过大,容易内存溢出.
带有缓冲区的复制的实例:建立一个与文件大小相同的字节数组:不建议使用,如果文件过大,容易内存溢出.
带有缓冲区的复制的实例:
<span style="font-size:18px;"><pre class="java" name="code">package cn.itcast.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4_CopyArray {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("致青春.mp3");
BufferedInputStream bis = new BufferedInputStream(fis); //创建缓冲区输入流对象,对fis进行包装
FileOutputStream fos = new FileOutputStream("copy.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos); //创建缓冲区输出流对象,对fos进行包装
int b;
while((b = bis.read()) != -1) { //bis.read()会将将文件上的数据读到缓冲区中,再从缓冲里获取数据
bos.write(b); //bos.write(b)是先将字节写到缓冲区里,然后在从缓冲区中一起写出
}
bis.close();
bos.close();
}
}
</span>
1.拷贝文件 a.使用FileInputStream和FileOutputStream, 逐个字节拷贝
b.使用FileInputStream和FileOutputStream, 定义一个大数组(length等于文件大小), 一次性拷贝
c.使用FileInputStream和FileOutputStream, 定义一个小数组(例如1024), 多次拷贝
d.使用BufferedInputStream和BufferedOutputStream内置的缓冲区, 逐个字节拷贝
2.标准化IO流操作的代码
a.finally嵌套
b.try close 标准异常处理的实例:
<span style="font-size:18px;">package cn.itcast.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo6_Tryfinally {
/**
* @param args
* IO标准的异常处理代码
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//demo1();
try(
//新特性
FileInputStream fis = new FileInputStream("aaa.txt");
FileOutputStream fos = new FileOutputStream("bbb.txt");
MyClose mc = new MyClose();
){
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
}
}
private static void demo1() throws FileNotFoundException, IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("aaa.txt");
fos = new FileOutputStream("bbb.txt");
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
} finally {
try {
if(fis != null)
fis.close();
} finally {
if(fos != null)
fos.close();
}
}
}
}</span>
将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出.
<span style="font-size:18px;">package cn.itcast.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Test3 {
/**
* @param args
* 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
FileOutputStream fos = new FileOutputStream("text.txt"); //创建输出流对象,关联text.txt
while(true) {
String line = sc.nextLine(); //键盘录入的字符串存入line中
if("quit".equals(line)) //判断如果是quit就退出
break;
fos.write(line.getBytes()); //写出的时候转换成字节数组写出去
fos.write("\r\n".getBytes()); //写出换行
}
fos.close();
}
}
</span>