IO流概述及其分类
- IO流概述:
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 - IO流分类
- 按照数据流向:
输入流 读入数据
输出流 写出数据 - 按照数据类型
字节流 可以读写任何类型的文件 比如音频 视频 文本文件
字符流 只能读写文本文件
- 按照数据流向:
FileOutputStream的构造方法
- IO流基类概述
- 字节流的抽象基类:
InputStream ,OutputStream。 - 字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
- 字节流的抽象基类:
- Io流的分类:
- 按照流向进行划分
输入流
输出流 - 按照操作的数据类型进行划分
字节流
字节输入流 InputStream 读
字节输出流 OutputStream 写
字符流
字符输入流 Reader 读
字符输出流 Writer 写
- 按照流向进行划分
FileOutputStream写出数据
- 构造方法:
FileOutputStream(File file)
FileOutputStream(String name)
注意事项:
创建字节输出流对象了做了几件事情?
a:调用系统资源创建a.txt文件
b:创建了一个fos对象
c:把fos对象指向这个文件
为什么一定要close()?
a: 通知系统释放关于管理a.txt文件的资源
b: 让Io流对象变成垃圾,等待垃圾回收器对其回收
代码示例:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class MyTest {
public static void main(String[] args) throws FileNotFoundException {
/*IO:用来进行设备之间的数据传输
*按照读写文件的类型可以分为:字节流和字符流
* 字节流可以对任何类型的文件进行读写(音频,文本,视频),末尾是Stream
* 字符流只能对文本类型的文件进行读写
* */
//文件输出流:FileOutputStream(File file)
// 构造方法摘要
// FileOutputStream(File file)
// 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
// FileOutputStream(String name)
// 创建一个向具有指定名称的文件中写入数据的输出文件流。
// FileOutputStream(String name, boolean append)
// 创建一个向具有指定 name 的文件中写入数据的输出文件流。
File file = new File("ab.txt");
FileOutputStream out = new FileOutputStream(file);
//输出流所关联的文件,如果不存在,会帮你自动创建
System.out.println("-----");
FileOutputStream fileOutputStream = new FileOutputStream("abc.txt");
//传入一个具体的文件路径字符串
}
}
FileOutputStream的三个write()方法
FileOutputStream的三个write()方法
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分
代码示例:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("a.txt");
//向文件中写入数据
out.write(97);//一次只能写入一个字节
out.write(98);
out.write(99);
out.write(new byte[]{100, 101, 102});//写入一个数组
// String str = "今天天气有点闷热";
// byte[] bytes = str.getBytes(str);//将字符串转换成数组
// out.write(bytes);
// out.write(bytes,0,3);//写入数组的一部分
out.close();//流使用完成关闭空间
//GBK编码一个汉字占两个字节,UTF-8 编码一个汉字占3个字节
}
}
FileOutputStream写出数据实现换行和追加写入
案例演示: FileOutputStream写出数据如何实现数据的换行
windows下的换行符只用是 \r\n
Linux \n
Mac \r
代码示例:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest4 {
public static void main(String[] args) throws IOException {
/**windows 下的换行 \r\n
*Linux 下的换行 \r
*Mac 下的换行 \n
* */
FileOutputStream out = new FileOutputStream("a.txt");
out.write("池塘边的榕树上知了在声声的叫着夏天".getBytes());
out.write("\r\n".getBytes());//不写换行,不换行
out.write("黑板上老师的粉笔还在叽叽喳喳写个不停".getBytes());
out.write("\r\n".getBytes());
out.write("等待着下课,等待着放学,等待游戏的童年".getBytes());
out.write("\r\n".getBytes());//写入一个换行符
out.close();//释放资源
}
}
案例演示: FileOutputStream写出数据如何实现数据的追加写入
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest5 {
public static void main(String[] args) throws IOException {
// FileOutputStream(String name)
// 创建一个向具有指定名称的文件中写入数据的输出文件流。
// FileOutputStream(String name, boolean append)
// 创建一个向具有指定 name 的文件中写入数据的输出文件流。append代表是否追加
FileOutputStream out = new FileOutputStream("a.txt",true);
//参数2:代表是否追加写入,true 追加写入 false 不追加
out.write("池塘边的榕树上知了在声声的叫着夏天".getBytes());
out.write("\r\n".getBytes());//写入一个换行符
out.write("黑板上老师的粉笔还在叽叽喳喳写个不停".getBytes());
out.write("\r\n".getBytes());//写入一个换行符
out.write("等待着下课,等待着放学,等待游戏的童年".getBytes());
out.write("\r\n".getBytes());//写入一个换行符
//释放资源
out.close();
}
}
FileOutputStream写出数据加入异常处理
案例演示:FileOutputStream写出数据加入异常处理
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 = null;
try {
out = new FileOutputStream("abn.txt");
out.write(100);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileInputStream读取数据一次一个字节
案例演示: int read():一次读取一个字节
如果没有数据返回的就是-1
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) throws IOException {
// FileInputStream(File file)
// 通过打开一个到实际文件的连接来创建一个 FileInputStream,
// 该文件通过文件系统中的 File 对象 file 指定。
// FileInputStream(FileDescriptor fdObj)
// 通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统
// 中某个实际文件的现有连接。
// FileInputStream(String name)
// 通过打开一个到实际文件的连接来创建一个 FileInputStream,
// 该文件通过文件系统中的路径名 name 指定
//FileInputStream 文件输入流
FileInputStream in = new FileInputStream(new File("a.txt"));
//读取文件中的数据
int len = in.read();
System.out.println(len);//一次只读一个字节
//一次读取一个字节,如果读取不到数据,返回的是 -1 我们要拿 -1 做判断看文件是否读取完了
len = in.read();
System.out.println(len);
len = in.read();
System.out.println(len);//一次只读一个字节
len = in.read();
System.out.println(len);
len = in.read();
System.out.println(len);//一次只读一个字节
len = in.read();
System.out.println(len);
in.close();//释放资源
}
}
代码示例2:
import java.io.*;
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//创建一个字符数组,充当缓存的空间
byte[] bytes = new byte[100];
int len = in.read(bytes);
//把文件中的数据,读取到容器中。返回值是读取到的有效字节个数
System.out.println(len);
for (byte aByte : bytes) {
System.out.println(aByte);
}
//把字节数组转成字符串:
//byte[] bytes1 = "str".getBytes();
String s = new String(bytes, 0, len);
System.out.println(s);
in.close();
}
}
代码示例3:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MyTest3 {
public static void main(String[] args) throws IOException {
//FileInputStream 文件输入流
FileInputStream in = new FileInputStream("a.txt");
byte[] bytes = new byte[1024];
int len = in.read(bytes, 0, 4);//一次从文件中读取一部分字节,放到容器中 从0开始读取四个
System.out.println(len);
String s = new String(bytes, 0, len);
System.out.println(s);
in.close();
}
}
字节流复制文本文件
:案例演示: 字节流一次读写一个字节复制文本文件
代码示例2:
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
//使用文件输入输出流进行文件复制
//ctrl+alt+空格 手动提示
FileInputStream in = new FileInputStream("MyTest.java");//关联源文件
FileOutputStream out = new FileOutputStream(new File("mytest222.java"));//关联目标文件
int len = 0;
while ((len = in.read()) != -1) {
//复制逻辑:读取一个字节,写入一个字节
//循环的读写
out.write(len);
out.flush();//刷新
}
//释放资源
in.close();
out.close();
}
}
字节流复制MP3
案例演示: 字节流一次读写一个字节复制MP3
代码示例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest2 {
public static void main(String[] args) throws IOException {
//读取一个字节写入一个字节
FileInputStream in = new FileInputStream("领悟1.mp3");
FileOutputStream out = new FileOutputStream("领悟2.mp3");
int len = 0;//定义一个变量记录读取到的字节
//循环读取
while((len = in.read())!=-1){
out.write(len);
out.flush();
}
//释放资源
in.close();
out.close();
}
}
FileInputStream读取数据一次一个字节数组
案例演示: int read(byte[] b):一次读取一个字节数组
返回的int类型的值表示的意思是读取到的字节的个数,如果没有数据了就返回-1
代码示例:
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) throws IOException {
//多复制一些字节,以提高速度
FileInputStream in = new FileInputStream("领悟1.mp3");
FileOutputStream out = new FileOutputStream("领222.mp3");
//定义一个缓冲区
byte[] bytes = new byte[1024 * 8];
int len = 0;//定义一个变量,记录每次读取到的有效字节个数
while((len = in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
//释放资源
in.close();
out.close();
}
}
FileInputStream读取数据的两种方式比较图解
FileInputStream读取数据的两种方式比较
代码示例:
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
copy1();
//程序执行消耗的时间:330毫秒
// copy2();
long end = System.currentTimeMillis();
// 程序执行消耗的时间:260毫秒
System.out.println("程序执行消耗的时间:"+(end-start)+"毫秒");
}
private static void copy2() throws IOException {
/**
* 高效的字节输入输出流BufferedInputStream底层加入了缓冲区,
* 该类实现了缓冲的输出流。通过设置这种输出流,应用程序就乐意将各个字节写入底层的输出流中
*而不必针对每次字节写入调用地层系统
*
*
* 构造方法摘要
* BufferedInputStream(InputStream in)
* 创建一个 BufferedInputStream 并保存其参数,
* 即输入流 in,以便将来使用。
* BufferedInputStream(InputStream in, int size)
* 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,
* 即输入流 in,以便将来使用。
* */
BufferedInputStream bfi = new BufferedInputStream(new FileInputStream("领悟1.mp3"));
BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream("领悟33.mp3"));
byte[] bytes = new byte[1024 ];
int len = 0;
while((len = bfi.read(bytes))!=-1){
bfo.write(bytes,0,len);
bfo.flush();
}
bfi.close();
bfo.close();
}
private static void copy1() throws IOException {
FileInputStream in = new FileInputStream("领悟1.mp3");
FileOutputStream out = new FileOutputStream("领悟31.mp3");
byte[] bytes = new byte[1024];
int len = 0;
while((len = in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}
}
BufferedOutputStream写出数据
缓冲思想
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,
也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
day21授课目录:
字符流出现的原因
String中的编解码问题
转换流