1.Java IO原理
- I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输如读/写文件,网络通讯等。
- Java程序中, 对于数据的输入/输出操作以”流(stream)"的方式进行。
- java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据。
- 输入input:读取外部数据(磁盘、 光盘等存储设备的数据)到程序(内存)中。
- 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
2、流的分类
2.1、简介
- 按操作数据单位不同分为:字节流(8 bit), 字符流(按字符)。
- 按数据流的流向不同分为:输入流,输出流。
- 按流的角色的不同分为:节点流,处理流/包装流。
(1)Java的IO流共涉及40多个类, 实际上非常规则,都是从如上4个抽象基类派生的。
(2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
2.2、IO流体系图
3、字节流InputStream和outputStream
3.1、InputStream字节输入流
InputStream抽象类是所有类字节输入流的超类
InputStream常用的子类:
- FilelnputStream:文件输入流
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
3.1.1、示例
按字节读,若文本文件中含有汉字,会出现乱码
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStream_ {
public static void main(String[] args) {
String namePath="d:\\hello.txt";
FileInputStream fileInputStream =null;
int readDataIndex=0;
try {
fileInputStream = new FileInputStream(namePath);
//从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
//如何返回-1 ,表示读取完毕
while ((readDataIndex=fileInputStream.read())!=-1){
System.out.print((char) readDataIndex);
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
按字符读取:
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStream_ {
public static void main(String[] args) {
String namePath="d:\\hello.txt";
FileInputStream fileInputStream =null;
int readDataLength=0;
//字节数组
byte[] buf=new byte[10];
try {
fileInputStream = new FileInputStream(namePath);
//从该输入流读取最多b.Length字节的数据到字节数组。此方法将阻塞,直到某些输入
//如果返回-1 ,表示读取完毕
//如果读取正常,返回实际读取的字节数
while ((readDataLength=fileInputStream.read(buf))!=-1){
System.out.print(new String(buf,0,readDataLength));
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
3.2、OutputStream字节输出流
3.2.1、示例
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStream_ {
public static void main(String[] args) {
String filePath="d:\\a.txt";
FileOutputStream fileOutputStream =null;
try {
//1. new File0utputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
//2. new File0utputStream(fiLePath, true) 创建方式,当写入内容是, 是追加到文件后面
fileOutputStream = new FileOutputStream(filePath,true);
//写入一个字节
fileOutputStream.write('H');
//写入一个字符串
String str="hello,world!";
//str.getBytes() 字符串-->字符数组
fileOutputStream.write(str.getBytes());
String str1="你好,世界!";
//将Len字节从位于偏移量off的指定字节数组写入此文件输出流
fileOutputStream.write(str1.getBytes(),0,str1.length());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.4、文件拷贝
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) {
String srcPath="d:\\lebran.jpeg";
String tarPath="D:\\ioTest\\lebran.jpeg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream=null;
//定义一个字节数组,以提高读取效率
byte[] bytes=new byte[1024];
int readLen=0;
try {
fileInputStream = new FileInputStream(srcPath);
fileOutputStream= new FileOutputStream(tarPath);
while ((readLen=fileInputStream.read(bytes))!=-1){
//读取到以后就立即输出
fileOutputStream.write(bytes,0,readLen);
}
System.out.println("拷贝完成!");
}catch (IOException e){
e.printStackTrace();
}finally {
//关闭输入流和输出流,释放资源
try {
if(fileInputStream!=null){
fileInputStream.close();
}
if(fileOutputStream!=null){
fileOutputStream.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
4、字符流FileReader和FileWriter
4.1、FileReader和FileWriter介绍
4.2、FileReader
单个字符读取:
import java.io.FileReader;
import java.io.IOException;
public class FileReader_ {
public static void main(String[] args) {
String namePath="d:\\sorry.txt";
FileReader fileReader =null;
int data=0;
try {
fileReader = new FileReader(namePath);
while ((data=fileReader.read())!=-1){
System.out.print((char) data);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fileReader!=null){
try {
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
按字符数组的长度读取:
import java.io.FileReader;
import java.io.IOException;
public class FileReader_ {
public static void main(String[] args) {
String namePath="d:\\sorry.txt";
FileReader fileReader =null;
char[] chars=new char[8];
int readLen=0;
try {
fileReader = new FileReader(namePath);
while ((readLen=fileReader.read(chars))!=-1){
System.out.print(new String(chars,0,readLen));
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fileReader!=null){
try {
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
4.3、FileWrtiter
import java.io.FileWriter;
import java.io.IOException;
public class FileWriter_ {
public static void main(String[] args) {
String namePath="d:\\note.txt";
FileWriter fileWriter=null;
int len=0;
try {
fileWriter=new FileWriter(namePath);
//1) write(int):写 入单个字符
fileWriter.write('H');
//2) write(char[]):写 入指定数组
char[] chars={'a','b','c'};
fileWriter.write(chars);
//4) write(char[],off, Len):写入指定数组的指定部分
fileWriter.write("长夜未央".toCharArray(),0,3);
//5) write (string) :写入整个字符串
fileWriter.write("刘亦菲");
//7) write (string, off,Len):写入字符串的指定部分
fileWriter.write("北京你好",0,2);
}catch (IOException e){
e.printStackTrace();
}finally {
//一定要关闭流,或者flush才能真正的把数据写入到文件
try {
//fileWriter.flush()
//关闭文件流,等价于flush()+关闭
fileWriter.close();
//源码
/*void implClose() throws IOException {
this.flushLeftoverChar((CharBuffer)null, true);
try {
while(true) {
CoderResult var1 = this.encoder.flush(this.bb);
if (var1.isUnderflow()) {
if (this.bb.position() > 0) {
this.writeBytes();
}
if (this.ch != null) {
this.ch.close();
} else {
this.out.close();
}
return;
}
if (var1.isOverflow()) {
assert this.bb.position() > 0;
this.writeBytes();
} else {
var1.throwException();
}
}
} catch (IOException var2) {
this.encoder.reset();
throw var2;
}
}*/
}catch (IOException e){
e.printStackTrace();
}
}
}
}
5、节点流和处理流