A:IO流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 java.io
B:IO流分类
a:按照数据流向 站在内存角度
输入流 读入数据
输出流 写出数据
b:按照数据类型
字节流 可以读写任何类型的文件 比如音频 视频 文本文件
字符流 只能读写文本文件
什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
如果你什么都不知道,就用字节流
A:IO流基类概述
a:字节流的抽象基类:
InputStream ,OutputStream。
b:字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
B:FileOutputStream的构造方法
由一个案例引出使用IO流写数据,由于字节流先出现就先学习字节输出流基类OutputStream,
使用具体子类FileOutputStream
public class Test1 {
public static void main(String[] args) throws IOException {
//FileOutputStream:文件输出流是用于将数据写入File
//按住ctrl点击添加书签
/*
* FileOutputStream(File file)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(File file, boolean append)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* 如果第二个参数是true ,则字节将被写入文件的末尾而不是开头,也就是追加写入,不会覆盖原内容
* FileOutputStream(FileDescriptor fdObj)
* 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
* FileOutputStream(String name)
* 创建文件输出流以指定的名称写入文件。
* FileOutputStream(String name, boolean append)
* 创建文件输出流以指定的名称写入文件。如果第二个参数是true
* 则字节将写入文件的末尾而不是开头,也就是追加写入,不会覆盖原内容
* */
//创建一个文件对象
File file = new File("a.txt");
//创建刚还文件对象的文件输出流
FileOutputStream outa = new FileOutputStream(file);
//创建文件输出流以指定的名称写入文件,这个构造函数会自动新建一个文件
FileOutputStream outb = new FileOutputStream("b.txt");
//创建文件输出流以指定的名称写入文件,字节写入文件的开头
FileOutputStream outc = new FileOutputStream("c.txt", false);
Scanner sc = new Scanner(System.in);
System.out.println("请输入要写入的内容");
String s = sc.nextLine();
//若要写入中文或一个字符串,就需要调用String类中的getByte函数
//将字符串提取为byte类型
byte[] writeText= s.getBytes();
/*void write(byte[] b)
将 b.length个字节从指定的字节数组写入此文件输出流。
void write(byte[] b, int off, int len)
将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。
void write(int b)
将指定的字节写入此文件输出流。*/
//一次写入一个字节,超出一个字节就会丢弃掉多余字节
outa.write(6);
outb.write('c');
//将转换好的字符串放入字节数组中,再调用write函数写入文件内
outc.write(writeText);
//最后要关闭
/*void close()
关闭此文件输出流并释放与此流相关联的任何系统资源。*/
outa.close();
outb.close();
outc.close();
}
}
public class Test2 {
public static void main(String[] args) throws IOException {
FileOutputStream out1 = new FileOutputStream("d.txt");
//往文件中写入数据
System.out.println("========往文件中写入一个字节========");
out1.write(97);
out1.write(100);
//如果多出一个字节,就会丢弃多余字节
//out1.write(200);
System.out.println("=======往文件中写入一个字节数组======");
FileOutputStream out2 = new FileOutputStream("e.txt");
//一次写入一个字节数组
ByteArrayOutputStream baos;
byte[] write = {94, 95, 96, 97, 98, 99};
out2.write(write);
System.out.println("=========往文件中写入一串中文=======");
FileOutputStream out3 = new FileOutputStream("f.txt");
String str="会感到十分光滑";
//字符串需要转换成字节数组才能使用字节流写入
byte[] chinese = str.getBytes();
out3.write(chinese);
System.out.println("===往文件中写入一个字节数组的一部分===");
FileOutputStream out4 = new FileOutputStream("g.txt");
String str1="会感到十分光滑";
//字符串需要转换成字节数组才能使用字节流写入
byte[] chinese1 = str.getBytes();
out4.write(chinese1,3,6);
//流使用完记得要释放资源
out1.close();
out2.close();
out3.close();
out4.close();
/*注意事项:
创建字节输出流对象了做了几件事情 ?
a : 调用系统资源创建a.txt文件
b:创建了一个文件对象
c:把该文件对象指向这个文件
流使用完毕,为什么一定要close() ?
a : 通知系统释放关于管理a.txt文件的资源
b:让Io流对象变成垃圾, 等待垃圾回收器对其回收*/
}
}
public class Test3 {
public static void main(String[] args) throws IOException {
System.out.println("============追加写入============");
//创建一个不会覆盖原内容的文件及文件对象
FileOutputStream outputStream = new FileOutputStream("h.txt", true);
outputStream.write("啊随风倒敢死队风格".getBytes());
//写入换行符
/* windows下的换行符是 \r\n
Linux \n
Mac \r
*/
outputStream.write("\r\n".getBytes());
outputStream.write("公司的风格岁的法国".getBytes());
outputStream.write("\r\n".getBytes());
outputStream.close();
}
}
public class Test4 {
public static void main(String[] args) {
//流的异常处理
FileOutputStream out = null;
try {
new FileOutputStream("i.txt");
} catch (IOException e) {
e.printStackTrace();
}finally{
//如果FileOutputStream对象不是null,则释放资源,否则打印异常信息
try{
if(out!=null){
out.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public class Text1 {
public static void main(String[] args) {
/*
* FileInputStream(File file)
* 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
* FileInputStream(FileDescriptor fdObj)
* 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
* FileInputStream(String name)
* 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。*/
try {
FileInputStream in1 = new FileInputStream("d.txt");
System.out.println("===========读取文件中的数据===========");
System.out.println("==============读一个字节=============");
/*int read()
* 从该输入流读取一个字节的数据。 */
int read = in1.read();
System.out.println(read);
int read1 = in1.read();
System.out.println(read1);
//如果读取不到有效的字节,就会返回-1 ,我们经常使用-1来判断这个文件的数据是否读取完毕。
int read2 = in1.read();
System.out.println(read2);
//流使用完毕,释放资源
in1.close();
System.out.println("============读一个字节数组============");
/*int read(byte[] b)
* 从该输入流读取最多 b.length个字节的数据为字节数组。 */
FileInputStream in2 = new FileInputStream("h.txt");
//创建一个字节数组缓存区
byte[] inBuffer = new byte[1024];
//把读取的字节,装进传进来的容器中
//返回的是一次实际读取的有效字节数
int len = in2.read(inBuffer);
System.out.println("读取到的有效字节数是" + len);
System.out.println(Arrays.toString(inBuffer));
//把读取到的字节数组转化成字符串显示
java.lang.String s = new java.lang.String(inBuffer, 0, len);
System.out.println(s);
//流使用完毕,释放资源
in2.close();
System.out.println("============读取有效的字节============");
/*int read(byte[] b, int off, int len)
* 从该输入流读取最多 len字节的数据为字节数组.*/
//一次从文件中读取3个字节,从0索引处开始把读取到的3个字节放入容器中
//如果读取不到有效字节返回的是 -1
FileInputStream in3 = new FileInputStream("g.txt");
//设置缓存区
byte[] inBuffer2 = new byte[1024];
int inLen = in3.read(inBuffer2, 0, 6);
System.out.println("读取到的有效字节个数:" + inLen);
/*inLen = in3.read(inBuffer2, 0, 6);
System.out.println("读取到的有效字节个数:" + inLen);*/
/*有效字节数就是有实际内容的字节
inLen = in3.read(inBuffer2, 0, 128);
System.out.println("读取到的有效字节个数:" + inLen);*/
String s1 = new String(inBuffer2, 0, inLen);
System.out.println(s1);
//流使用完毕,释放资源
in3.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
//高效的字节输入输出流
//BufferedInputStream
//BufferedOutputStream
try {
test1();//使用单字节复制完成共耗时29146ms
test2();//复制完成共耗时16933毫秒
test3();//使用缓存区复制完成共耗时12ms
test4();//复制完成共耗时12毫秒
/*同一个文件,当使用字节复制的时候高效流比普通流的使用的时间缩短了一半
* 但是当使用缓存复制的时候,高效流和普通流使用的时间一样*/
} catch (IOException e) {
e.printStackTrace();
}
}
private static void test1() throws IOException {
System.out.println("============使用普通流字节复制============");
FileInputStream dataInCompare = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
FileOutputStream dataOutCompare = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3");
int inDataCompare = 0;
//调用系统函数计算开始复制的时间
long startCompare = System.currentTimeMillis();
while ((inDataCompare = dataInCompare.read()) != -1) {
dataOutCompare.write(inDataCompare);
dataOutCompare.flush();
}
//调用系统函数计算复制复制完成的时间
long endCompare = System.currentTimeMillis();
System.out.println("使用单字节复制完成共耗时"+(endCompare-startCompare)+"ms");
//释放资源
dataInCompare.close();
dataOutCompare.close();
}
private static void test2() throws IOException {
System.out.println("============使用高效流字节复制============");
/* BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
*/
BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3"));
int by=0;
long start = System.currentTimeMillis();
while ((by = in.read()) != -1) {
out.write(by);
out.flush();
}
long end = System.currentTimeMillis();
System.out.println("复制完成共耗时" + (end - start) + "毫秒");
//释放资源
in.close();
out.close();
}
private static void test3() throws IOException {
System.out.println("============使用普通流缓存复制============");
//定义1kb=1024byte的数据,这里开辟了8kb的缓存区
byte[] dataBuffer = new byte[1024*8];
FileInputStream dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
FileOutputStream dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3");
//定义一个变量,来记录每次读取到的有效字节个数
int len = 0;
//调用系统函数计算开始复制的时间
long start = System.currentTimeMillis();
//read函数返回的是当前读取到的有效字节数
while ((len = dataIn.read(dataBuffer)) != -1) {
//将字节数组缓存区中的数据写入文件
dataOut.write(dataBuffer,0,len);
dataOut.flush();
}
//调用系统函数计算复制复制完成的时间
long end = System.currentTimeMillis();
System.out.println("使用缓存区复制完成共耗时"+(end-start)+"ms");
//释放资源
dataIn.close();
dataOut.close();
}
private static void test4() throws IOException {
System.out.println("============使用高效流缓存复制============");
BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3"));
//一次读取一个字节,写入一个字节来复制mp3
byte[] bytes = new byte[1024 * 8];
int by = 0;
long start = System.currentTimeMillis();
while ((by = in.read(bytes)) != -1) {
out.write(bytes,0,by);
out.flush();
}
long end = System.currentTimeMillis();
System.out.println("复制完成共耗时" + (end - start) + "毫秒");
//释放资源
in.close();
out.close();
}
}
public class Test1 {
public static void main(String[] args) {
try {
System.out.println("============方式一============");
//一个字节一个字节的复制
FileInputStream in = new FileInputStream("h.txt");
FileOutputStream out = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\h.txt");
int data = 0;
while ((data = in.read()) != -1) {
out.write(data);
out.flush();
}
//释放资源
in.close();
out.close();
System.out.println("============方式二============");
/*1byte=8bit
* 1kb=1024byte
* 1M=1024kb
* 1G=1024M
* 1T=1024G*/
//一次复制一个字节的数据过于缓慢
//如果要复制一个1M大小的MP3文件的话
//一次复制一个字节的数据就会不停地读写1024的平方次
//要是我们读写的文件大小是NM,则复制文件的时间复杂度为O(N*1024*1024)
//所以此处我们引入缓存区的概念
//一次缓存1024*1024byte=1M的数据,这样时间复杂度相对于O(N)就可以看成是O(1)
System.out.println("============缓存区复制============");
//定义1kb=1024byte的数据,这里开辟了8kb的缓存区
byte[] dataBuffer = new byte[1024*8];
FileInputStream dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
FileOutputStream dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3");
//定义一个变量,来记录每次读取到的有效字节个数
int len = 0;
//调用系统函数计算开始复制的时间
long start = System.currentTimeMillis();
//read函数返回的是当前读取到的有效字节数
while ((len = dataIn.read(dataBuffer)) != -1) {
//将字节数组缓存区中的数据写入文件
dataOut.write(dataBuffer,0,len);
dataOut.flush();
}
//调用系统函数计算复制复制完成的时间
long end = System.currentTimeMillis();
System.out.println("使用缓存区复制完成共耗时"+(end-start)+"ms");
//释放资源
dataIn.close();
dataOut.close();
System.out.println("==========单字节复制同一个文件==========");
FileInputStream dataInCompare = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
FileOutputStream dataOutCompare = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3");
int inDataCompare = 0;
//调用系统函数计算开始复制的时间
long startCompare = System.currentTimeMillis();
while ((inDataCompare = dataInCompare.read()) != -1) {
dataOutCompare.write(inDataCompare);
dataOutCompare.flush();
}
//调用系统函数计算复制复制完成的时间
long endCompare = System.currentTimeMillis();
System.out.println("使用单字节复制完成共耗时"+(endCompare-startCompare)+"ms");
//释放资源
dataInCompare.close();
dataOutCompare.close();
/*由以上我们可以看到,复制大文件,合适的缓存区能够大量的减少代码的时间复杂度*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Test2 {
public static void main(String[] args) {
//流的异常处理
FileInputStream dataIn=null;
FileOutputStream dataOut=null;
try {
dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\Java\\MyNote\\Java笔记\\Day19JavaSE——IO概述&异常&File文件类\\04视频\\录像160.mp4");
dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\录像160.mp4");
//1、定义字节数组充当缓冲区
byte[] dataBuffer = new byte[1024];
//2.定义一个变量。用来记录每次读取到的有效字节个数
int len=0;
//3.频繁的读写
long start = System.currentTimeMillis();
while ((len = dataIn.read(dataBuffer)) != -1) {
dataOut.write(dataBuffer,0,len);
dataOut.flush();
}
long end = System.currentTimeMillis();
System.out.println("复制完成共耗时" + (end - start) + "毫秒");
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(dataIn!=null){
dataIn.close();
}
if(dataOut!=null){
dataOut.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
em.currentTimeMillis();
System.out.println(“复制完成共耗时” + (end - start) + “毫秒”);
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(dataIn!=null){
dataIn.close();
}
if(dataOut!=null){
dataOut.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}