java中的IO(1)
I/O流基础概念
按照流的方向分为输入流和输出流
输入流:只能读取数据,不能写入数据
输出流:只能写入数据,不能读取数据
输入和输出是一个相对概念,我们一般以程序为中心,由程序写入数据到其他位置,是输出流,由其他位置将数据写入到程序,是输入流
I/O流可以实现的功能:
文件上传/下载,读写文件,文件拷贝,文件夹拷贝…
流是什么?
流是管道,数据在管道中以先入先出的方式进行流动
流的分类:
按照操作单元分:
字节流 : 数据以字节为单位 -->万能流
字符流 : 数据以字符为单位 -->只能操作纯文本文件
按照功能划分:
节点流:程序直接与数据源连接,和实际的输入/输出节点连接;
处理流:对节点流进行包装,扩展原来的功能,由处理流执行IO操作
按照处理的数据单位分为字节流和字符流
字节流:操作的数据单元是8位的字节。InputStream、OutputStream作为抽象基类。
字符流:操作的数据单元是字符。以Writer、Reader作为抽象基类。
字节流可以处理所有数据文件,若处理的是纯文本数据,建议使用字符流
使用字节流读取本地文件
一次只读取一个字节
import java.io.FileInputStream;
import java.io.IOException;
public class ClassIO02 {
public static void main(String[] args) throws IOException {
//与数据源建立连接,并建立管道
FileInputStream fileInputStream = new FileInputStream("D:/FileTest/a.txt");
//定义一个int类型的变量,用来表示是否从数据源读到了数据,没读到为-1
int num = -1;
//每次只读取一个字节的数据,进行循环
while((num=fileInputStream.read())!=-1){
//将读到的字节数转换成char类型输出
System.out.println((char)num);
}
//关闭输入流
fileInputStream.close();
}
}
一次读取多个字节,使用字节数组进行存储
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ClassIO03 {
public static void main(String[] args) throws IOException {
//与数据源建立连接,并建立管道
InputStream fileInputStream = new FileInputStream("D:/FileTest/a.txt");
//定义一个字节数组用来接收读到的字节
byte[] a = new byte[1024];
//定义一个int类型的变量,用来表示是否从数据源读到了数据,没读到为-1
int len = -1;
//每次读一个数组大小的数据,进行循环
while((len=fileInputStream.read(a))!=-1){
//将读到的字节数转换成char类型输出 索引为0到len
System.out.println(new String(a,0,len));
}
//关闭流
fileInputStream.close();
}
}
使用字节流写入本地文件
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class ClassIO04 {
public static void main(String[] args) throws IOException {
//与目的地建立连接,并建立管道
//若目的地不存在,系统会帮忙创立
OutputStream outputStream = new FileOutputStream("D:/FileTest/a.txt",true);
//定义一个有值得字节数组,用于写出
byte[] arr = "我爱你,我的家,我的家,我的天堂".getBytes();
//写入
outputStream.write(arr);
//刷出
outputStream.flush();
//关闭流
outputStream.close();
}
}
使用字节流拷贝文件
public class IOTest {
public static void main(String[] args) throws IOException {
//和数据源建立连接,并建立管道
InputStream inputStream = new FileInputStream("D:/FileTest/a.txt");
//和目的地建立连接,并建立管道,若不存在目的地,则系统会帮忙建立
OutputStream outputStream = new FileOutputStream("D:/FileTest/b.txt");
//定义一个1024大小的字节数组,用来接受从数据源中读到的字节
byte[] arr = new byte[1024];
//定义一个len,表示数组接收到数据的长度,若没有接收到,则len为-1;
int len = -1;
//判断是否从数据源读到了数据
while((len=inputStream.read(arr)) !=-1){
//如果读到了数据,将数据写入目的地
outputStream.write(arr,0,len);
}
//刷出
outputStream.flush();
//关闭输出
outputStream.close();
//关闭输入
inputStream.close();
}
}
以上代码都是将编写过程中的异常向上抛出,我们也可以捕获异常
import java.io.*;
public class IOTest02 {
public static void main(String[] args) {
//因为作用域得原因,我们必须将变量声明在try{}catch语句块之外
InputStream inputStream = null;
OutputStream outputStream = null;
try {
//与数据源,目的地建立连接,并建立管道 true为在源文件后追加,默认false,覆盖
outputStream = new FileOutputStream("D://FileTest/b.txt",true);
inputStream = new FileInputStream("D://FileTest/江南-龙族4奥丁之渊.txt");
//定义一个1024大小的字节数组,用来接受从数据源中读到的字节
byte[] arr = new byte[1024];
//定义一个len,表示数组接收到数据的长度,若没有接收到,则len为-1;
int len = -1;
//判断是否从数据源读到了数据
while((len = inputStream.read(arr))!=-1){
//如果读到了数据,将数据写入目的地
outputStream.write(arr,0,len);
}
//刷出
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//使用if语句,避免空指针异常
if(outputStream!=null){
try {
//关闭输出流
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream!=null){
try {
//关闭输入流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
jdk7新特性 : try–with–resources 异常处理机制
注意 : 要求使用try–with–resources结构自动关闭的资源必须实现AutoCloseable接口(包含Closeable)
public class IOTest03 {
public static void main(String[] args) throws FileNotFoundException {
InputStream inputStream = new FileInputStream("D://FileTest/a.txt");
OutputStream outputStream = new FileOutputStream("D://FileTest/b.txt");
//jdk9之后
//将这两个引用交给try{}catch{}管理
/*try (outputStream;inputStream){
byte[] arr = new byte[1024];
int len = -1;
int count = 0;
while((len = inputStream.read(arr))!=-1){
outputStream.write(arr,0,len);
count++;
}
System.out.println(count);
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}*/
//jdk9之前
//需要在try中重新声明一个引用
try (OutputStream outputStream2 = outputStream;InputStream inputStream2 = inputStream){
byte[] arr = new byte[1024];
int len = -1;
int count = 0;
while((len = inputStream2.read(arr))!=-1){
outputStream2.write(arr,0,len);
count++;
}
System.out.println(count);
outputStream2.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流与字节流的用法大致相同
使用字符流读取本地文件
public class Class007_CopyFile {
public static void main(String[] args) throws IOException {
//拷贝文件
//1.与数据源|目的地建立联系
//2.构建流
Reader rd = new FileReader("D://xixi.txt");
Writer rt = new FileWriter("D://hehe.txt");
//3.读写
char[] car = new char[1024];
int len = -1;
while((len=rd.read(car))!=-1){
rt.write(car,0,len);
}
//4.刷出
rt.flush();
//5.关闭
rt.close();
rd.close();
}
}
缓冲流
/*
* 字节缓冲流
缓冲流Buffered : 提高节点流的读写效率
通过内部的缓冲区数组实现降低操作磁盘的次数,提高读写效率
缓冲区数据可以通过构造器指定,可以使用默认的大小 1024*8
字节的节点流 :
文件字节流
字节数组流
字节流的功能流
字节缓冲流
字节缓冲输入流BufferedInputStream : 提高字节输入节点流的读写效率
字节缓冲输出流BufferedOutputStream : 提高字节输出节点流的读写效率
都没有新增方法,可以发生多态
字符流的节点流 :
文件字符流
字符流的功能流 :
字符缓冲流 : 提高字符节点流读写效率
字符输入缓冲流 BufferedReader
新增方法 : String readLine() 读取一行文本。
字符输出缓冲流 BufferedWriter
新增方法 : void newLine() 写入行分隔符。
存在新增方法,不能发生多态
注意 : 功能流|处理流都需要包裹节点流进行使用
* */
public class ClassIOBuffer01 {
public static void main(String[] args) {
testByteBuffer("D://FileTest/a.txt","D://FileTest/d.txt");
try {
testCharBuffer("D://FileTest/a.txt","D://FileTest/f.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
//字符缓冲流
public static void testCharBuffer(String inputFileName,String outputFileName) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(inputFileName));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(outputFileName));
String mag = null;
while((mag = bufferedReader.readLine())!=null){
bufferedWriter.write(mag);
bufferedWriter.newLine();
}
bufferedWriter.flush();
bufferedWriter.close();
bufferedReader.close();
}
//字节缓冲流
public static void testByteBuffer(String inputFileName,String outputFileName){
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(inputFileName));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputFileName));
byte[] arr = new byte[1024];
int len;
while((len = bufferedInputStream.read(arr))!=-1){
bufferedOutputStream.write(arr,0,len);
}
bufferedOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedOutputStream!=null) {
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedInputStream!=null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}