一.IO流
1.IO流概述
A:IO流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 java.io
B:IO流分类
a:按照数据流向 站在内存角度
输入流 读入数据
输出流 写出数据
b:按照数据类型
字节流 可以读写任何类型的文件 比如音频 视频 文本文件
字符流 只能读写文本文件
什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
如果你什么都不知道,就用字节流
2.IO流的基类
字节流的抽象基类:InputStream、OutputStream
字符流的抽象基类:Reader、Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
二.字节流
1.字节输入流
1.FileOutputStream概述及构造方法
FileOutputStream :文件输出流 是用于将数据写入 File
FileOutputStream(File file)创建一个文件输出流,来关联一个文件 当关联的文件不存在时,会自动帮你创建这个文件
FileOutputStream out = new FileOutputStream(String s)直接传入文件的字符串路径,如果不存在,会自动帮你创建这个文件
FileOutputStream fos = new FileOutputStream("a.txt");
注意事项:
创建字节输出流对象了做了几件事情 ?
a : 调用系统资源创建a.txt文件
b:创建了一个fos对象
c:把fos对象指向这个文件
流使用完毕,为什么一定要close() ?
a : 通知系统释放关于管理a.txt文件的资源
b:让Io流对象变成垃圾, 等待垃圾回收器对其回收
fos.close();
package org.westos.demo5;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) throws IOException {
/* FileOutputStream(File file)创建一个文件输出流,
来关联一个文件 当关联的文件不存在时,会自动帮你创建这个文件
*/
File file = new File("aaaa.txt");
//相当于 file.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(file);
//直接传入文件的字符串路径,如果不存在,会自动帮你创建这个文件
FileOutputStream out = new FileOutputStream("bbbb.txt");
}
}
2.往文件中写入数据
public void write(int b):每次写一个字节 超过一个字节 丢弃掉多余的部分
public void write(byte[] b):一次写如一个字节数组
public void write(byte[] b,int off,int len):一次写入一个字节数组的一部分,参数2:这个字节的起始索引 参数3:你要写几个字节的长度
package org.westos.demo5;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class MyTest2 {
public static void main(String[] args) throws IOException {
//创建一个文件输出流,来关联一个文件 当关联的文件不存在时,会自动帮你创建这个文件
FileOutputStream out = new FileOutputStream("d.txt");
//每次往文件中写入一个字节
out.write(97);//a
out.write(98);//b
out.write(99);//c
out.write(100);//d
//超过一个字节回丢弃掉多余部分
//out.write(128);//?
//一次写入一个字节数组
out.write(new byte[]{65,66,67,68});
//写入中文首先要先转换成字节数组
String s="本伟卢氏";
byte[] bytes = s.getBytes();
out.write(bytes);
//一次写入一个字节数组的一部分
/* public void write(byte[] b,int off,int len):
一次写入一个字节数组的一部分,参数2:这个字节的起始索引
参数3:你要写几个字节的长度*/
byte[] bytes1 = new byte[]{99,100,101,102,103,104};
out.write(bytes1,1,3);
//流使用完毕要记得释放资源
out.close();
}
}
3.往文件中追加写入数据
每次写入都会覆盖掉以前所写的内容,想往文件中继续写入数据.
FileOutputStream(File file, boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name, boolean append)
创建一个向具有指定 name 的文件中写入数据的输出文件流
参数2:是否要追加写入,true 追加写入。false 不追加
package org.westos.demo6;
import javax.crypto.Mac;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("a.txt",true);
/* FileOutputStream(File file, boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name, boolean append)
创建一个向具有指定 name 的文件中写入数据的输出文件流
参数2:是否要追加写入,true 追加写入。false 不追加*/
out.write(66);
out.write(67);
out.write(68);
out.write("本伟卢氏".getBytes());
/*
windows下的换行符只用是 \r\n
Linux \n
Mac \r
*/
out.write("\r\n".getBytes());
out.write("大战卡布奇诺阿玉".getBytes());
out.write("\r\n".getBytes());
}
}
4.流的异常处理
一般会为了简洁而抛出异常,但是不太符合要求,所以会使用try...catch...finally来处理
package org.westos.demo6;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest2 {
public static void main(String[] args) {
//流的异常处理
FileOutputStream out=null;
try {
// System.out.println(3/0);
out = new FileOutputStream("b.txt");
}catch (IOException e){
e.printStackTrace();
/*
1.流使用完要关闭,不在作用域,往外提出
* out.close();
* */
}finally {
/*2.不管有没有异常都挺要关闭流*/
if (out==null) {
/*3.如果在try的第一行就碰到了异常,则流无法创建成功,不需要释放资源*/
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.字节输出流
1.FileInputStream概述及构造方法
FileInputStream 从文件系统中的某个文件中获得输入字节。
FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String name)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。*/
2.从文件中读取数据
一次读取一个字节
package org.westos.demo4;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @Author: ShenMouMou
* @Company:西部开源教育科技有限公司
* @Description:简简单单,只为教育。
*/
public class MyTest {
public static void main(String[] args) throws IOException {
// FileInputStream 从文件系统中的某个文件中获得输入字节。
/* FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String name)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。*/
//输入流所关联的文件,如果不存在,就会报错
FileInputStream in= new FileInputStream("a.txt");
//输入输入流,读取文件中的数据
//一次读取一个字节
int by = in.read();
System.out.println(by);
by = in.read();
System.out.println(by);
by = in.read();
System.out.println(by);
by = in.read();
System.out.println(by);
//如果读取不到有效的字节,就会返回-1 ,我们经常使用-1来判断这个文件的数据是否读取完毕。
by = in.read();
System.out.println(by);
//流使用完毕,记得释放资源
in.close();
}
}
一次读取一个字节数组
package org.westos.demo7;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class MyTest2 {
public static void main(String[] args) throws IOException {
//一次读取一个字节数组
FileInputStream in = new FileInputStream("bbb.txt");
// read(byte[] b)方法:从此输入流中将最多b.length个字节的数据读入一个字节数组中
//创建一个字节数组,来充当容器
byte[] b = new byte[1024];
//将读取到的字节写入这个字节数组中
int len = in.read(b);
System.out.println(len);//4
System.out.println(b);//[B@1540e19d
System.out.println("================");
//将字节数组转换为字符串
/*
* 会将整个数组中元素都转换成字符串输出
* */
System.out.println(Arrays.toString(b));
String s = new String(b, 0, len );
System.out.println(s);
in.close();
}
}
一次读取一个字节数组的一部分
package org.westos.demo7;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("aa.txt");
//一次读取一个字节数组的一部分
byte[] bytes = new byte[1024];
// 将读取到的字节写入这个字节数组中,从0索引处开始,长度为2
//返回值表示字节数组的有效长度
/*注意:
这里的1表示的是从文件中读取两个字节,不是从字符串的1索引处开始读取,而是
从0索引处开始读取,读取两个字节,存储在字节数组的1所以处
* */
int le = in.read(bytes, 1, 2);
System.out.println(le);
System.out.println(Arrays.toString(bytes));
System.out.println("===============");
le = in.read(bytes, 0, 2);
System.out.println(le);
System.out.println(Arrays.toString(bytes));
System.out.println("===============");
//如果读取不到有效字节返回的是 -1
le = in.read(bytes, 0, 2);
System.out.println(le);
System.out.println(Arrays.toString(bytes));
System.out.println("===============");
le = in.read(bytes, 0, 2);
System.out.println(le);
System.out.println(Arrays.toString(bytes));
}
}
3.字节流复制文本文件
方式1:读取一个字节,写一个字节
package org.westos.demo2;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) throws IOException {
// 方式1:读取一个字节,写一个字节
FileInputStream in = new FileInputStream("C:\\Users\\user\\Pictures\\Saved Pictures\\zpc.jpg");
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\demo3\\zpc.jpg");
int len=0;
while ((len=in.read())!=-1){
out.write(len);
out.flush();
}
in.close();
out.close();
}
}
方式2:一次读取一个字节数组
package org.westos.demo;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest4 {
public static void main(String[] args) throws IOException {
//一次读取一个字节数组进行
FileInputStream in = new FileInputStream("C:\\Users\\user\\Pictures\\Saved Pictures\\zpc.jpg");
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\demo2\\zpc.jpg");
//1.定义一个字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 8];
//2.定义一个变量。用来记录每次读取到的有效字节个数
int len = 0;
long start = System.currentTimeMillis();
//3.进行复制
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
long end=System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
}
4.流的异常处理
package org.westos.demo2;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest3 {
public static void main(String[] args) {
//一次读取一个字节数组进行
/*(1)流使用完要关闭,不在作用域,提出去*/
FileInputStream in = null;
FileOutputStream out = null;
try {
/*
* (3)System.out.println(1/0);
* */
in = new FileInputStream("C:\\Users\\user\\Pictures\\Saved Pictures\\zpc.jpg");
out = new FileOutputStream("C:\\Users\\user\\Desktop\\demo4\\zpc.jpg");
//1.定义一个字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 8];
//2.定义一个变量。用来记录每次读取到的有效字节个数
int len = 0;
long start = System.currentTimeMillis();
//3.进行复制
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
long end=System.currentTimeMillis();
System.out.println(end-start+"毫秒");
} catch (IOException e) {
e.printStackTrace();
} finally {
/*(2)不管有没有异常都要关闭流*/
try {
/*
* (3)为空表示try的第一行就有异常,没能创建成功*/
if (in!=null){
/*(1)流使用完要关闭,不在作用域,提出去*/
in.close();
}
if (out!=null){
out.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
5.高效字节输入输出流
BufferedOutputStream 和 BufferedInputStream自带缓冲区的字节输出流
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
package org.westos.demo2;
import java.io.*;
public class MyTest4 {
public static void main(String[] args) throws IOException{
//test1();耗时34148毫秒
//test2();耗时17207毫秒
//test3();耗时16毫秒
// test4();耗时16毫秒
}
private static void test1() throws IOException {
//一次读取一个字节,写入一个字节
FileInputStream in = new FileInputStream("C:\\Users\\user\\Desktop\\music\\陈一发儿 - 童话镇.mp3");
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\music2\\陈一发儿 - 童话镇.mp3-1111");
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 test2() throws IOException {
/* BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。*/
BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\user\\Desktop\\music\\陈一发儿 - 童话镇.mp3"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\user\\Desktop\\music2\\陈一发儿 - 童话镇.mp3-buffer"));
//一次读取一个字节,写入一个字节
int len=0;
long start = System.currentTimeMillis();
while ((len=in.read())!=-1){
out.write(len);
out.flush();
}
long end = System.currentTimeMillis();
System.out.println("耗时" + (end - start) + "毫秒");
}
private static void test3() throws IOException {
//一次读取一个字节数组
FileInputStream in = new FileInputStream("C:\\Users\\user\\Desktop\\music\\陈一发儿 - 童话镇.mp3");
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\music2\\陈一发儿 - 童话镇.mp3-2222");
byte[] bytes = new byte[1024*8];
long start = System.currentTimeMillis();
//len表示每次读取的有效字节个数
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
long end = System.currentTimeMillis();
System.out.println("耗时" + (end - start) + "毫秒");
}
private static void test4() throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\user\\Desktop\\music\\陈一发儿 - 童话镇.mp3"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\user\\Desktop\\music2\\陈一发儿 - 童话镇.mp3-44444"));
int len=0;
long start = System.currentTimeMillis();
byte[] bytes = new byte[1024*8];
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
long end = System.currentTimeMillis();
System.out.println("耗时" + (end - start) + "毫秒");
}
}