File类
File类是文件或目录路径名的抽象表示。
Java中路径名的书写:
(1)使用“/”(使用左斜杠)--------推荐使用!!!
Java要实现跨平台,而Linux中的路径使用“/”,Windows中的路径一般使用“\”,也能识别“/”,故统一使用“/”。
String path="D:/java300/IO_study/IO.png";
(2)使用常量拼接
常量File.separator表示与操作系统相关的路径分隔符,在不同操作系统下,转成响应的路径分隔符。
String path="D:"+File.separator+"java300"+File.separator+"IO_study01"+File.separator+"IO.png";
常用API
API | 说明 |
separator(static常量) | 路径分隔符 |
File(String path) | 构造器 |
getName() getPath() getAbsolutePath() getParent() | 文件名 路径名 |
exists() isFile() isDirectory() | 判断状态 |
length() | 文件的字节数 |
createNewFile() delete() | 创建新文件 删除文件 |
mkdir() mkdirs() | 创建目录,如果父目录链不存在,则一同创建 |
list() | 列出下级名称 |
listFiles() | 列出下级File对象 |
listRoots() | 根路径 |
注意:使用File构造器(包含给定的路径),不会创建文件,必须调用createNewFile()函数才可以创建新的文件。
字符集
在编码与解码过程中,存在很多种字符集,比如:ASCII,UTF-8,Unicode等
- ASCII:1个字符占1个字节
- Unicode:1个字符占2个字节
- UTF-8:变长字节,1个英文占1个字节,1个汉字占2-3个字节
编码:(字符--->字节):
package cn.csu.io;
import java.io.UnsupportedEncodingException;
public class Demo {
public static void main(String[] args) throws UnsupportedEncodingException {
String msg="性命生命使命";
byte [] datas=msg.getBytes(); //默认使用项目工程的字符集GBK
System.out.println(datas.length);
byte [] datas1=msg.getBytes("utf-8");
System.out.println(datas1.length);
byte [] datas2=msg.getBytes("GBK");
System.out.println(datas1.length);
byte [] datas3=msg.getBytes("UTF-16LE");
System.out.println(datas1.length);
}
}
解码(字节--->字符):
package cn.csu.io;
import java.io.UnsupportedEncodingException;
public class Demo {
public static void main(String[] args) throws UnsupportedEncodingException {
String msg="性命生命使命";
byte [] datas=msg.getBytes(); //默认使用项目工程的字符集GBK
String str1=new String(datas,0,datas.length,"utf-8");
System.out.println(str1);
String str2=new String(datas,0,datas.length,"GBK");
System.out.println(str2);
String str3=new String(datas,0,datas.length,"UTF-16LE");
System.out.println(str3);
}
}
IO流
(1)流的分类
按数据流的流向分为:输入流和输出流(以程序为中心)
- 输入流:数据源到程序(InputSteam、Reader读进来)
- 输出流:程序到目的地(OutputSteam、Writer写出去)
按操作的数据单位分为:字节流和字符流
- 字节流:按照字节读取数据(InputStream、OutputSteam)
- 字符流:按照字符读取数据(Reader、Writer),因为文件编码的不同,从而有了对字符进行高效操作的字符流对象,但是字符流的底层还是基于字节流操作,自动搜寻了指定的字符集。
按流的角色分为:节点流和处理流(按照是否直接与特定的地方相连,比如磁盘,内存,设备等)
- 节点流:可以直接从数据源或目的地读写程序
- 处理流:不直接连接到数据源或目的地,是其他流进行封装,目的是简化操作和提高性能
注意:节点流处于IO操作的第一线,所有的操作必须通过节点流进行;处理流可以对其他流进行处理(提高效率或操作灵活性)
(2)四个抽象类
- InputSteam:字节输入流的父类,数据单位为字节。
- OutputSteam:字节输出流的父类,数据单位为字节。
- Reader:字符输入流的父类,数据单位为字符。
- Writer:字符输入流的父类,数据单位为字符。
InputStream中提供了read()重载方法:(根据返回值-1,可以判断是否读取完成)
- int read ():从输入流读取数据的下一个字节。值字节被返回作为int范围0-255。如果没有字节可用,因为已经到达了流的末尾,则返回值为-1。(一个一个读)(返回读取到的字节对应的int字符)
- int read(byte [] b):从输入流读取一些字节数,并将它们存储到缓冲区b,实际读取的字节数作为整数返回,若到达了流的末尾,则返回值为-1。(一组一组读)(返回读取长度)
- int read(byte [] b,int off,int len):从输入流读取len字节的数据到一个字节数组,指定从字符数组的off位置开始存储,实际读取的字节数作为整数返回,若到达了流的末尾,则返回值为-1。
OutputSteam中提供了write()重载方法:
- void write(int b):将指定的一个字节写入此输出流。
- void write(byte [] b):将指定的一个字节数组写入此输出流。
- void write(byte [] b,int off,int len):从指定的字节数组写入len字节,并且从off位置开始。
Reader中提供了read()重载方法(根据返回值-1,可以判断是否读取完成)
- int read():读一个字符,返回读取到的字符int类型,如果已经到达流的末尾,则返回值为-1。
- int read(char [] cbuff):将字符读入数组,返回读取的字符数,如果已经到达流的末尾,则返回值为-1。
- int read(char [] cbuff,int off,int len):将字符读入数组的一部分,如果已经到达流的末尾,则返回值为-1。
Writer中提供了write()重载方法
- void write(int c):写一个指定字符。
- void write(char [] cbuff):写入一个字符数组。
- void write(char [] cbuff,int off,int len):写入字符数组的一部分。
- void write(String str):写入一个字符串。
- void write(String str,int off,int len):写入一个字符串的一部分。
read():
package cn.csu.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Demo2 {
public static void main(String[] args) {
File file = new File("I:/sqc.txt");
InputStream is=null;
try {
is = new FileInputStream(file);
int temp; //接收数据
try {
//测试read()方法,返回每次读取的字节(表示为int类型)
while((temp=is.read())!=-1){
System.out.print((char)temp);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
read(byte [] b):
package cn.csu.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Demo3 {
public static void main(String[] args) {
File file=new File("I:/sqc.txt");
InputStream is=null;
byte [] s=new byte[3];
try {
is=new FileInputStream(file);
int temp; //接收长度
try {
//测试read(byte [] b)方法,返回每次读取的字节数
while((temp=is.read(s))!=-1){
System.out.println(temp);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
操作流程可以看做是搬家的过程,如果从程序搬到其他地方,第一步需要确定搬家的目的的,即确定源;第二步需要选择搬家公司,即选择流;第三步需要确定一件一件得搬还是一卡车一开车得搬,即具体操作;第四步搬家完成,需要付费,让搬家公司离开,即释放资源。
操作流程:
- 确定源
- 选择流
- 具体操作(一个一个读,一组一组读,一个一个写,一组一组写)
- 释放资源
标准步骤:(掌握)
package cn.csu.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Demo {
public static void main(String[] args) {
//1.创建源
File file = new File("I:/sqc.txt");
InputStream is=null;
try {
//2.选择流
is = new FileInputStream(file);
int temp;
try {
//3.具体操作(这里选择read()方法,一个字节一个字节读取)
while((temp=is.read())!=-1){
System.out.print((char)temp);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
//4.释放资源,关闭字节输入流
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(3)字节流
操作不同的数据源,需要使用不同的流。当操作的数据源是文件时,可以采用文件字节流;当操作的数据源是内存中的字节数组时,可以采用字节数组流。
3.1 文件字节流
FileInputStream:字节文件输入流,从文件系统中的某个文件中获得输入的字节,用于读取诸如图像数据之类的原始字节流。
构造方法:
//通过File对象创建FileInputStream对象
FileInputStream(File file);
//通过路径名创建FileInputStream对象
FileInputStream(String path);
常用方法:
覆盖和重写了父类的常用方法,read()方法的具体实现(一次读一个字节,一次读一个字节数组)。
FileOutputStream:字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。
构造方法:
//通过File对象创建FileOutputStream对象
FileOutputStream(File file);
//通过路径名创建FileOutputStream对象
FileOutputStream(String path);
//通过File对象创建FileOutputStream对象,并指定写入方式(追加还是覆盖)
FileOutputStream(File file,boolean append);
//通过路径名创建FileOutputStream对象,并指定写入方式(追加还是覆盖)
FileOutputStream(File file,boolean append);
常用方法:
覆盖和重写了父类的常用方法,write()方法的具体实现(一次写一个字节,一次写一个字节数组)。
示例:文件的拷贝(包含字节的读入和写出)
第一步,确定原地址和目的地址,即建立源地址和目的地址的File对象;
第二步,确定输入流和输出流,这里选择文件字节输入流和文件字节输出流;
第三步,确定读写的方式,即按照给定的字节数组大小读写字节;
第四步,分别关闭输出流和输入流,释放资源。
package cn.csu.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Demo {
public static void main(String[] args) {
File file = new File("I:/小丑.jpg");
File file_copy=new File("I:/拷贝.jpg");
InputStream is=null;
OutputStream os=null;
try {
is=new FileInputStream(file);
os=new FileOutputStream(file_copy);
int temp;
byte [] flush=new byte [1024];
while((temp=is.read(flush))!=-1){
os.write(flush,0,flush.length);
}
System.out.println("拷贝成功!!!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.2 字节数组流
ByteArrayInputStream:字节数组输入流,从字节数组中输入数据到程序中。
ByteArrayOutputStream:字节数组输出流,从程序中输出数据到字节数据中。
package cn.csu.io;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Demo {
public static void main(String[] args) {
String str="ahlghalhglahgasodihg";
byte [] datas=str.getBytes();
InputStream is=new ByteArrayInputStream(datas);
int temp;
try {
while((temp=is.read())!=-1){
System.out.print((char)temp);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.2 缓冲字节流
BufferedInputStream:字节缓冲输入流,提高了读取效率。
构造方法:
//创建一个BufferedInputStream并保存其参数,即输入流is,以供将来使用
BufferedInputStream(InputStream is);
//创建BufferedInputStream具有指定缓冲区大小,并保存其参数,即输入流is,以供将来使用。
BufferedInputStream(InputStream is,int size);
BufferedOutputStream:字节缓冲输出流,提高了写出效率。
构造方法:
//创建一个新的缓冲输出流,以将数据写入指定的底层输出流
BufferedOutputStream(OutputStream os);
//创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
BufferedOutputStream(OutputStream os,int size);
使用缓冲字节流和文件字节流效率比较:
//使用文件字节流拷贝文件
public class Demo {
public static void main(String[] args) {
File file1=new File("I:/sqc.mp4");
File fiel2=new File("I:/文件字节流_拷贝.mp4");
InputStream is=null;
OutputStream os=null;
try {
is=new FileInputStream(file1);
os =new FileOutputStream(fiel2);
int temp;
byte [] datas=new byte[1024];
try {
long start=System.currentTimeMillis();
while((temp=is.read(datas))!=-1){
os.write(datas,0,temp);
}
long end=System.currentTimeMillis();
System.out.println("文件拷贝成功!");
System.out.println("拷贝用时:"+(end-start)+"ms");
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//使用缓冲字节流拷贝文件
public class Demo {
public static void main(String[] args) {
File file1=new File("I:/sqc.mp4");
File file2=new File("I:/缓冲字节流_拷贝.mp4");
InputStream is =null;
OutputStream os=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
is =new FileInputStream(file1);
os=new FileOutputStream(file2);
bis=new BufferedInputStream(is);
bos=new BufferedOutputStream(os);
int temp;
byte [] datas=new byte[1024];
try {
long start=System.currentTimeMillis();
while((temp=bis.read(datas))!=-1){
bos.write(datas, 0, temp);
}
long end=System.currentTimeMillis();
System.out.println("文件拷贝成功!");
System.out.println("拷贝用时:"+(end-start)+"ms");
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}if(bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(4)字符流
4.1 文件字符流
FileReader:InputStreamReader类的直接子类,用来读取字符文件的便捷类,使用默认的字符编码。
FileWriter:OutputStreamWriter类的直接子类,用来写入字符文件的便捷类,使用默认字符编码。
//文件字符流(读入)
public class Demo {
public static void main(String[] args) {
File file=new File("I:/sqc.txt");
Reader reader=null;
try {
reader=new FileReader(file);
char [] datas=new char[1024];
int temp;
try {
while((temp=reader.read(datas))!=-1){
String str=new String(datas,0,temp);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//文件字符流(写出)
public class Demo {
public static void main(String[] args) {
File file=new File("I:/sqc_writer.txt");
Writer writer=null;
try {
writer=new FileWriter(file);
writer.write("我们都是中国人!!!");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(writer!=null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2 缓冲字符流
BufferedReader:字符缓冲流,从字符输入流中读取文本,缓冲各个字符,从而实现字符,数组和行的高效读取。
构造方法:
//创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader reader);
//创建一个使用指定大小输入缓冲区的缓冲字符输入流
BufferedWriter(Reader reader,int size);
特有方法:(根据返回值null,可以判断是否读取完成)
//读一行文字,返回包含行的内容的字符串,不包括任何终止字符,如果到达流的末尾,则返回null。
String readLine();
示例:
//使用read()方法
public class Demo {
public static void main(String[] args) {
File file=new File("I:/sqc.txt");
Reader reader=null;
BufferedReader bufferedReader=null;
try {
reader=new FileReader(file);
bufferedReader=new BufferedReader(reader);
int temp;
char [] datas=new char [1024];
try {
while((temp=bufferedReader.read(datas))!=-1){
System.out.print(new String(datas,0,temp));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//使用readLine()方法
public class Demo {
public static void main(String[] args) {
File file=new File("I:/sqc.txt");
Reader reader=null;
BufferedReader bufferedReader=null;
try {
reader=new FileReader(file);
bufferedReader=new BufferedReader(reader);
String str;
try {
while((str=bufferedReader.readLine())!=null){
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedWriter:字符缓冲流,将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入。
构造方法:
//创建一个使用默认大小输出缓冲区的缓冲字符输出流
BufferedWriter(Writer writer);
//创建一个使用给定大小输出缓冲区的新缓冲字符输出流
BufferedWriter(Writer writer,int size);
特有方法:
//写一行行分隔符(换行)
void newLine();
示例:
public class Demo {
public static void main(String[] args) {
File file=new File("I:/xl.txt");
Writer writer=null;
BufferedWriter bufferedWriter=null;
try {
writer=new FileWriter(file);
bufferedWriter=new BufferedWriter(writer);
String str1="大纲公安哈";
String str2="噶按时";
bufferedWriter.write(str1);
bufferedWriter.newLine();
bufferedWriter.write(str2);
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(writer!=null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bufferedWriter!=null){
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2 字节字符转换流
InputStreamReader:从字节流到字符流的桥梁,它读取字节,并使用指定的charset字符集将其解码为字符。
构造方法:
//创建一个使用默认字符集的InputStreamReader
InputStreamReader(InputStream is);
//创建使用给定字符集的InputStreamReader
InputStreamReader(InputStream is,Charset cs);
//创建使用给定字符集解码器的InputStreamReader
InputStreamReader(InputStream is,CharsetDecoder dec);
//创建使用指定字符集的InputStreamReader
InputStreamReader(InputStream is,String charsetName);
OutputStreamWriter:从字符流到字节流的桥梁,它写出字节,并使用指定的charset字符集将其编码为字节。
//创建使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStrema os);
//创建使用给定字符集的OutputStreamWriter
OutputStreamWriter(OutputStream os,Charset cs);
//创建使用给定字符集编码器的OutputStreamWriter
OutputStreamWriter(OutputStream os,CharsetEncoder enc);
//创建使用指定字符集的OutputStreamWriter
OutputStreamWriter(OutputStream os,String charsetName);
示例:
如果数据源是网络资源,使用URL的openStream()方法获得网络资源的字节输入流,可以使用该字节输入流read()方法读取字节流中的字节,并保存在本地。也可以使用read()方法读取字节流中的字节,使用eclipse中默认编解码方式打印到控制台,但是www.jd.com这个url使用utf-8编码,而eclipse中项目默认使用GBK编解码,故直接打印在控制台上会出现乱码。
public class Demo {
public static void main(String[] args) {
try {
URL url=new URL("https://www.jd.com");
InputStream is=url.openStream();
File file=new File("I:/jd.txt");
FileOutputStream fileOutputStream=new FileOutputStream(file);
byte [] datas=new byte[1024];
int temp;
while((temp=is.read(datas))!=-1){
System.out.println(new String(datas,0,temp));
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
若要将从字节输入流读到的字节打印在控制台,且不出现乱码,可以使用字节字符转换流,使用特定的charset字符集,比如这个www.jd.com这个url使用utf-8编码,则在字节流转换为字符流的时候,指定使用utf-8进行编码,这样在控制台上打印的字符就不会出现乱码了。
//爬取京东网页源码,并打印在控制台
public class Demo {
public static void main(String[] args) {
try {
URL url=new URL("https://www.jd.com");
InputStream is=url.openStream();
InputStreamReader inputStreamReader=new InputStreamReader(is,"UTF-8");
char [] datas=new char[1024];
int temp;
while((temp=inputStreamReader.read(datas))!=-1){
System.out.println(new String(datas,0,temp));
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(5)节点流
该类型可以从或者向一个特定的地方或者节点读写数据。主要类型如下:
(6)处理流
该类型是对一个已经存在的流的连接和封装,通过所封装的流的功能调用实现数据读写,处理流的构造方法总是要带一个其他流对象作为参数,一个流对象经过其他流的多次封装,叫做流的连接,主要有以下几种:
6.1 缓冲流
该类型内部增加了缓冲区,可以提高对流的操作效率。
- BufferedInputStream
- BufferedOutputStream
- BufferedReader
- BufferedWriter
6.2 转换流
该类型是字节流和字符流之间的桥梁,该流对象可以对读取到的字节数据进行指定解码的解码转换,也可以对写出的字符数据进行指定编码的编码转换。
- InputStreamReader
- OutputStreamWriter
6.3 数据流
该类型可以方便地处理八大基本数据类型和字符串,不光保留了数据还保留了数据类型。
注意:写出后读取;读取的顺序与写出的顺序一致
- DataInputStream:数据输入流允许应用程序以独立于机器的方式从底层输入流读取原始Java数据类型。
- DataOutputStream:数据输出流使应用程序以便携方式将原始Java数据类型写入输出流,然后应用程序可以使用数据输入流来读取数据。
示例:
public class Demo {
public static void main(String[] args) throws IOException {
OutputStream outputStream=new FileOutputStream(new File("I:/xl.txt"));
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
dataOutputStream.writeDouble(34.4534);
dataOutputStream.writeBoolean(true);
dataOutputStream.writeInt(444);
dataOutputStream.writeUTF("中南大学");
InputStream inputStream=new FileInputStream(new File("I:/xl.txt"));
DataInputStream dataInputStream=new DataInputStream(inputStream);
double a=dataInputStream.readDouble();
boolean b=dataInputStream.readBoolean();
int c=dataInputStream.readInt();
String d=dataInputStream.readUTF();
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
6.4 打印流
- PrintStream:可以很方便地打印各种数据值的表示
注意:System.out返回一个PrintStream对象
示例:
public class Demo {
public static void main(String[] args) {
//方式一:简写
System.out.println("中南大学");
//方式二:全写
PrintStream printStream=System.out;
printStream.print("中南大学");
}
}
6.5 对象流
该类型的流可以把类作为一个整体进行存取。
注意:
- 当使用对象流写入或者读取对象的时候,必须保证该对象是序列化的
- 对象序列化即将对象转换成二进制数据流的一种实现手段,通过将对象序列化,可以方便的实现对象的传输及保存,在Java中提供了ObjectInputStream和ObjectOutputStream这两个类用于序列化对象的操作。
- ObjectInputStrema:重要方法---readObject()
- ObjectOutputStream:重要方法---wirteObject(Object obj),被写入的对象必须实现一个接口:Serializable
示例:
public class Student implements Serializable {
private String name;
private int sid;
private String gender;
private double grade;
public Student() {
}
public Student(String name, int sid, String gender, double grade) {
super();
this.name = name;
this.sid = sid;
this.gender = gender;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", sid=" + sid + ", gender=" + gender + ", grade=" + grade + "]";
}
}
public class Demo {
public static void main(String[] args) {
File file=new File("I:/xl.txt");
OutputStream outputStream=null;
InputStream inputStream=null;
ObjectOutputStream objectOutputStream=null;
ObjectInputStream objectInputStream=null;
try {
outputStream=new FileOutputStream(file);
objectOutputStream=new ObjectOutputStream(outputStream);
Student student=new Student();
student.setName("marden");
student.setSid(666);
student.setGender("男");
student.setGrade(100.45);
objectOutputStream.writeObject(student);
inputStream=new FileInputStream(file);
objectInputStream=new ObjectInputStream(inputStream);
Student stu=(Student) objectInputStream.readObject();
System.out.println(stu);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(objectOutputStream!=null){
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(objectInputStream!=null){
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
总结:
当使用Java IO的时候,需要首先确定使用字节流还是字符流;其次根据数据源的不同,选择合适的节点流和处理流,比如数据源是文件,可以采用文件字节流,比如数据源是内存中的字节数组,可以采用字节数组流。