IO流基础
概念
I的全称input表示输入
O的全称output表示输出
流是一个在两个设备之间数据传输管道
输入流的特征:读
输出流的特征:写
IO流的作用:在设备之间进行数据传输
体系
流向分为两大类:
- 输入流
- 输出流
数据类型分为两大类:
-
字节流
字节输入流:InputStream
字节输出流:OutputStream
-
字符流
入:Reader
出:Writer
注意:字节流用来读写bytes,字符流用来读写chars,字符 1-----两字节----16bit
字节流
InputStream是所有字节输入流的父类,它也是一个抽象类,它定义了抽象方法由子类实现
它的子类:AudioInputStream:读取音频视频的输入流
ByteArrayInputStream:读取字节数组的输入流
FilterInputStream:带有过滤器的输入流
FileInputStream:读取磁盘文件的输入流
ObjectInputStream:读取对象的输入流
StringBufferInputStream:字符串缓冲区输入流
PipedInputStream:管道输入流
字节输入特征:它所有的子类后缀都以InputStream结束
OutputStream是所有输出流的父类,它也是抽象类
ByteArrayOutputStream:写字节数组
FilterOutputStream:带有过滤器的输出流
FileOutputStream:读取磁盘文件的输出流
ObjectOutputStream:对象的输出流
PipedOutputStream:管道输出流
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
抽象基类 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
注意:字符流和字节流的使用范围:字节流一般用来处理图像,视频,以及PPT,Word类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,字节流可以用来处理纯文本文件,但是字符流不能用于处理图像视频等非文本类型的文件。
输出流例题
1,创建文件
package a.demo;
import java.io.FileOutputStream;
//使用new关键字创建FileOutputStream
//以字符串作为参数指数路径
//打印对象
public class demo5 {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("a.txt"))
{
System.out.println(fos);
}catch (Exception e){
e.printStackTrace();
}
}
}
/*
1.创建一个基于字节的磁盘输出流
2.在当前工程下创建一个a.txt文件
3.将磁盘的a.txt文件和Java程序进行绑定
*/
2,单一字符写入文件
package b;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/*
创建FileOutStream对象,将Java程序的数据写入到磁盘
*/
public class demo1 {
public static void main(String[] args) {
try{
/*
创建FileOutputStream对象,指定磁盘路径,在创建过程中会检查a.txt是否存在
如果不存在就创建a。txt,如果存在不创建文件
*/
FileOutputStream d = new FileOutputStream("a.txt");
//将数据写入磁盘,此时会将66转换为对应的ASCII码“B”,将B写入a.txt
d.write(66);
//关闭通道,释放new 对象
d.close();
}catch (Exception
e){
e.printStackTrace();
}
}
}
3,写入字符串
package b;
import java.io.FileOutputStream;
import java.util.Arrays;
/*
定义一个字符串hello
创建文件输出流FileOutStream对象,指定路径
调用write方法,将字符串hello转换为字符数组然后写入
*/
public class demo2 {
public static void main(String[] args) {
String str="hello";
try { //创建文件输出流对象
FileOutputStream d = new FileOutputStream("aa.txt");
//对字符串hello进行编码,转换为字节数组
byte[] s=str.getBytes();
System.out.println(Arrays.toString(s));
//将转换的字节数组写进磁盘中
d.write(str.getBytes());
//释放资源
d.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
4,将字符串中字母写入文件
package b;
import java.io.FileOutputStream;
import java.util.Arrays;
/*
定义一个字符串hello
创建文件输出流FileOutStream对象,指定路径
调用write(byte[],int,len)方法将he写入磁盘,写入之前先对字符串进行编码
关闭资源
*/
public class demo3 {
public static void main(String[] args) {
try{
FileOutputStream s = new FileOutputStream("aaa.txt");
String c="hello";
byte[] a = c.getBytes();
System.out.println(Arrays.toString(a));
s.write(a,0,2);
s.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
追加写
1,追加写入字符串
package b;
import java.io.FileOutputStream;
/*
1.使用带有两个参数的构造方法创建FileOutputStream对象
参数1:磁盘文件的路径,此时相对当前工程的路径
参数2:追加写的标志位,它是一个Boolean类型的参数
true:在原有内容的情况下进行追加(不覆盖)
false:覆盖
*/
public class demo4 {
public static void main(String[] args) {
try {
//true表示在原来文件的基础进行追加,false覆盖
FileOutputStream d = new FileOutputStream("aa.txt",true);
d.write(" world".getBytes());
d.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
2,换行写
第一次调用write方法写入hello,第二次换行
Windows系统换行符是\r\n,此时表示回车并换行
Unix Linux系统下换行符是\n
MAC系统下换行符是\r
package b;
import java.io.FileOutputStream;
/*
步骤:
1 创建FileOutputStream对象,绑定b.txt
2 调用write方法将hello进行编译
3 调用write方法将\r\n进行编译
4 调用write方法将hello进行编译
*/
public class demo5 {
public static void main(String[] args) {
try {
FileOutputStream d = new FFileOutputStream("b.txt");
d.write("hello".getBytes());
d.write("\r\n".getBytes());
//回车换行
d.write("hello".getBytes());
d.close();
}catch (Exception e){
System.err.println("写入文件失败");
e.printStackTrace();
}
}
}
易错点
- 没有使用try catch组合(可以使用public static void main(String[] args) throws Exception)
- try模块一旦close()方法执行之前出现异常无法关闭
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZrtACgMv-1615802286440)(C:\Users\acer\AppData\Roaming\Typora\typora-user-images\image-20210309195437836.png)]
定义一个FileOutputStream对象写入数据,将关闭资源的操作使用try模块完成
*OutputStream是所有输入流的父类,它是一个抽象类
*FileOutputStream是一个具体类去继承OutputStream
输入流
主要用于将磁盘数据读取到Java程序中
作用:用来读取数据
常用构造方法:
new FileInputStream(String name)创建一个文件输入流对象,参数是用来字符串表示的路径new FileInputStream(File name)创建一个文件输入流对象,参数使用File对象表示的一个路径
常用的成员方法:
- int read(int):每次读取一个byte的数据
- int read(byte[] data):每次读取***多个***byte数据,参数是一个字节数组,此时用来读取结果,有效字节作为返回值
package c;
import java.io.FileInputStream;
/*
磁盘数据读取到Java程序中
步骤:
1 定义try
2 在try模块中创建FileInputStream对象,
并指定文件的路径
3 调用read()方法读取数据
*/
public class demo1 {
public static void main(String[] args) {
try {
FileInputStream a = new FileInputStream("c.txt");
int data=a.read();
int data1=a.read();
int data2=a.read();
int data3=a.read();
int data4=a.read();
System.out.println(data);
System.out.println(data1);
System.out.println(data2);
System.out.println(data3);
System.out.println(data4);
//文件读取完毕情况下,再次调用read()方法返回-1,表示读取文件末尾
}catch (Exception e){
System.err.println("读取失败");
e.printStackTrace();
}
}
}
***3***打印字节串的个数
package c;
import java.io.FileInputStream;
import java.util.Arrays;
/*
1 定义try
2 在try里面创建FileINputStream对象,并且指定磁盘文件的路径
3 调用read方法读取多个bytes,读取的结果保留到字节数组
4 打印读取的结果
*/
public class demo2 {
public static void main(String[] args) {
try {
FileInputStream d = new FileInputStream("c.txt");
byte [] data=new byte[3];
//length 表示读取的有效字节数
int length=d.read(data);
System.out.println("length="+length+" data="+ Arrays.toString(data));
//第二次读取
length=d.read(data);
System.out.println("length="+length+" data="+ Arrays.toString(data));
//第三次读取
length=d.read(data);
System.out.println("length="+length+" data="+ Arrays.toString(data));
}catch (Exception e){
System.err.println("读取失败");
e.printStackTrace();
}
}
}
注意:可以使用循环for
当length=-1时,该字节串读取完成
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TP0h2ziJ-1615802286441)(C:\Users\acer\AppData\Roaming\Typora\typora-user-images\image-20210310210253424.png)]
***4***连续打印字符串
package c;
import java.io.FileInputStream;
import java.io.InputStream;
public class demo3 {
public static void main(String[] args) {
try {
InputStream f = new FileInputStream("c.txt");
int data=0;
//先执行read()方法,读取一个磁盘数据
//数据用data存储,然后执行判断(-1表示没有数据可读)
while((data=f.read()) !=-1){
System.out.print(data+"\t");
}
}catch(Exception e){
System.err.println();
e.printStackTrace();
}
}
}
文件拷贝
将D://copy.txt里面文件拷贝到当前工程路径的copy.txt路径下
拷贝步骤:
- 建立输入管道FileInputStream对象和输出管道FileOutputStream
- 使用输入管道的read()方法读取数据,将读取的数据存储到程序
- 输出管道将读取的数据写入到目的磁盘
package c;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/*
将D://copy.txt里面文件拷贝到当前工程路径的copy.txt路径下
1.定义try
2.定义输入管道FileInputStream对象和输出管道FileOutputStream
3.定义变量data用于存储读取的数据
4. 使用while循环从磁盘读取数据,读取到-1停止读取
5. 将读取的数据使用输出管道写入到目的磁盘
*/
public class demo4 {
public static void main(String[] args) {
try {
FileInputStream a = new FileInputStream("D://copy.txt");
FileOutputStream b = new FileOutputStream("copy.txt");
//用来存储从此安排你读取的数据
int data=0;
while((data=a.read())!=-1){
b.write(data);
}
}catch (Exception e){
System.err.println("拷贝数据失败");
e.printStackTrace();
}
}
}
//直接在idea文本中
拷贝图片
将D盘目录下的miku.jpg拷贝到当前工程路径下
package c;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/*
步骤:
1.定义try
2.定义输入管道FileInputStream对象和输出管道FileOutputStream
3.定义变量存储读取的数据
4.调用while循环
*/
public class demo5 {
public static void main(String[] args) {
long in=System.currentTimeMillis();
try {
InputStream a = new FileInputStream("D://miku.jpg");
OutputStream b = new FileOutputStream("miku.jpg");
int data=0;
while((data=a.read())!=-1){
b.write(data);
long end=System.currentTimeMillis();
System.out.println("耗时"+(end-in));
}
}catch (Exception e){
System.err.println("失败");
e.printStackTrace();
}
}
}
运行时间过长,要优化该程序
需要设置一个字节数组作为缓冲区,字节数组的大小为2的10次方(1024),一次不再读取1024个byte
package c;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/*
步骤:
1.定义try
2.定义输入管道FileInputStream对象和输出管道FileOutputStream
3.定义变量存储读取的数据
4.定义变量int length 存储每次读取的有效字节
5.使用循环一次读取多个byte,当length等于-1停止读取
6.调用输出管道的write(byte,int,int)方法将读取的数据写入目的路径
*/
public class demo5 {
public static void main(String[] args) {
long in=System.currentTimeMillis();
try {
InputStream a = new FileInputStream("D://miku.jpg");
OutputStream b = new FileOutputStream("miku.jpg");
//定义缓冲区,存储读取的数据
byte [] data=new byte[1024];
int length=0;
//每一次读取磁盘1024个byte
//将读取的数据存储到字节数组data中,并且返回读取值
while((length=a.read(data))!=-1){
b.write(data,0,length);
long end=System.currentTimeMillis();
System.out.println("耗时"+(end-in));
}
}catch (Exception e){
System.err.println("失败");
e.printStackTrace();
}
}
}
= new FileOutputStream("miku.jpg");
//定义缓冲区,存储读取的数据
byte [] data=new byte[1024];
int length=0;
//每一次读取磁盘1024个byte
//将读取的数据存储到字节数组data中,并且返回读取值
while((length=a.read(data))!=-1){
b.write(data,0,length);
long end=System.currentTimeMillis();
System.out.println("耗时"+(end-in));
}
}catch (Exception e){
System.err.println("失败");
e.printStackTrace();
}
}
}