JAVA高级特性——Java I/O
JAVA是通过流对文件进行输入和输出的(输入和输出是站在程序的角度),流是以先进先出的方式发送和接受数据的通道。
按流向分:
流分为输入流(InputStream和Reader)和输出流(OutputStream和Write)
按处理数据单元分:
流分为字节流(InputStream和OutputStream)和字符流(Reader和Write)
字节是8位通用字节流,基本单位字节,字符流是16位Unicode字符流,基本单位是字符。InputStream和OutputStream、Reader和Write都是抽象类。
一、字节流
字节输入流
InputStream(父类、抽象类)
int read()——从输入流读取下一个字节数据
int read(byte[]b)——从数组b中读取数据
int read(byte[]b,int off,int len)——从数组b中读取数据,从off开始,读到len长度
void close()——关闭流
FireInputStream(InputStream的子类·)
new FireInputStream(File file)——读取file文件
new FireInputStream(String path)——读取path路径的xx文件(指定文件名)
字节输出流
OutputStream(父类、抽象类)
void write(int)——将指定字节数写出去
void write(byte[]b)——将指定字节数放到字节数组b中写出去
void write(byte[]b,int off,int len)——从字节数组b中从off开始,写到len长度
void void close()——关闭流
void flush()——清空缓冲区
FireOutputStream(OutputStream的子类)
new FireOutputStream(File file)——写到file文件(覆盖)
new FireOutputStream(String path)——写到path路径的xx文件(指定文件名,也是覆盖)
new FireOutputStream(String path,boolean append)——追加写到某个路径或文件下可以指定覆盖或者不覆盖(TRUE不覆盖)
二、字符流
字符输入流
Reader(父类、抽象类)
int read()——从输入流读取下一个字符数据
int read(byte[]b)——从数组b中读取字符数据
int read(byte[]b,int off,int len)——从数组b中读取数据,从off开始,读到len长度
void close()——关闭流
InputStreamReader(可以指定字符编码格式来读取,解决中文乱码问题)需要字节流
new InputStreamReader(InputSteam)——把字节流封装成字符流
new InputStreamReader(InputSteam,String charSetName)——charSetName指定编码
FileReader(是InputStreamReader的子类)
new FileReader(File file)
new FileReader(String path)
缓冲流BufferedReader:
readLine()—— 一行一行地读取,提高效率
字符输出流
Writer(父类、抽象类)
wirter(String)
flush()——清空缓存
close()
OutputStreamWriter(可以指定字符编码格式来保存)需要字节流
new OutputStreamWriter(OutputSteam)——把字节流封装成字符流
new OutputStreamWriter(OutputSteam,String charSetName)——charSetName指定编码
FileWriter
new FileWriter(File file)
new FileWriter(String path)
new FileWriter(String path,boolean append)——追加写到某个路径或文件下可以指定覆盖或者不覆盖(TRUE不覆盖)
缓冲流BufferedWriter:(带缓冲区)
writer(String)
newLine()——换行
flush()
中文乱码:
原因:文件编码格式和程序环境编码格式不一样,导致乱码。
System.out.print(System.getProperty("file.encoding"))获取当前程序编码格式。
二进制文件读写
二进制读写文件是需要字节流进行关联的,使用方法与字节流类似。
可以按照与平台无关的方式从流中都区基本数据类型的数据,如int、float、double、boolean等等
DateInputStream
DateOutputStream
FileInputStream fis=new FileInputStream(path);
DateInputStream dis=new FileInputStream(fis);
序列化和反序列化
将对象存储为二进制的序列,反序列化就是将二进制序列化存储的再转成对象输出出来
步骤:
对象类实现Seralizabe接口
创建对象输出流
调用writeObject()方法将对象写入文件
关闭对象输出流
//写一个学生集合
public class Text2 {
public static void main(String[] args) {
//创建学生集合
List <Students> lis=new ArrayList<Students>();
lis.add(new Students("张三",18,"男"));
lis.add(new Students("鸟子",18,"女"));
lis.add(new Students("浩子",18,"男"));
ObjectOutputStream obj=null;
ObjectInputStream oobj=null;
try {
//创建输出流
obj=new ObjectOutputStream(new FileOutputStream("stu.txt"));
//写出去的是二进制保存起来
obj.writeObject(lis);
//创建输入流,读取stu.txt文件
oobj=new ObjectInputStream(new FileInputStream("stu.txt"));
//读取的是集合,用集合接收,要进行强转
List <Students> liss=(List <Students>)oobj.readObject();
//将集合遍历输出
for (Students students : liss) {
System.out.println(students.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
oobj.close();
obj.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
注意:对象类一定要实现Seralizabe接口,否则会报NotSeralizabeException异常
反序列化的时候要进行类型强制转换,因为readObject()读取出来的是Object类。
若对象的某些属性不想被序列化,加上关键字tranient,可以屏蔽某些敏感字段的序列化,反序列后不可获取此属性。
import java.io.*;
/**
* 将图片转为数组,输出成文件,再读取这个文件,获得这个数组,还原成图片
* @author Administrator
*
*
*/
public class Text3 {
public static void main(String[] args) {
//获取图片aa.jpg,将图片信息保存到数组b中
byte []b=Text3.imgArry("aa.jpg");
//通过数组b写到文件bb.txt中去
Text3.writeByteimg(b, "bb.txt");
byte []c=Text3.imgin("bb.txt");
Text3.writeimg(c, "cc.jpg");
}
/**
* 用字节流获取图片,把字节数组用ByteArrayOutputStream 写到 bao里面去,,可以返回一个字节数组
* @param path
* @return
*/
public static byte[] imgArry(String path){
InputStream inImg=null;
ByteArrayOutputStream bao=new ByteArrayOutputStream();
try {
inImg=new FileInputStream(path);
byte [] b=new byte[1024];
int len=-1;
//将图片的所有字节通过数组b读取出来在写到bao里面去
while((len=inImg.read(b))!=-1) {
bao.write(b, 0, len);
}
//返回bao字节数组
return bao.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bao.close();
inImg.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 用二进制写出图片,保存到文件去
* @param imgs
* @param path
*/
public static void writeByteimg(byte []imgs,String path) {
DataOutputStream outimg=null;
try {
outimg=new DataOutputStream(new FileOutputStream(path));
outimg.write(imgs);
outimg.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outimg.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取二进制保存的图片,放到一个字节数组中
*/
public static byte[] imgin(String path) {
DataInputStream imgin=null;
try {
imgin=new DataInputStream(new FileInputStream(path));
//创建一个字节数组,数组长度等于图片返回的实际字节数
byte[] b=new byte[imgin.available()];
//读取图片信息放入b中,返回b
imgin.read(b);
return b;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
imgin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 将图片输出
*/
public static void writeimg(byte[]img,String path) {
OutputStream ow=null;
try {
ow=new FileOutputStream(path);
ow.write(img);
ow.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ow.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
浙公网安备 33010602011771号