文章目录
一、简介
1.什么是IO?
- IO是输入input输出output的首字母缩写形式,直观意思是计算机输入输出,它描述的是计算机的数据流动的过程,因此IO第一大特征是有数据的流动;另外,对于一次IO,它究竟是输入还是输出,是针对不同的主体而言的,不同的主体有不同的描述。
2.什么是数据源?
数据源分为:源设备、目标设备。
- 源设备:为程序提供数据,一般(input)输入流
- 设备:程序数据目的地,一般(output)输出流
3.流?
- 一个抽象、动态的概率,是一连串连续动态数据集合。
注意:输入/输出流的划分是相对程序而言的
4.Java中四大IO抽象类
4.1InputStream
表示字节输入流的所有类的父类。继承InputSteam的流都是用于程序输入数据,且数据单位为字节(8bit)。
4.1.1常用方法
- int read():读取一个字节的数据,并将字节的值返回INT类型(0-252)如果未读取到字节返回-1,结束。
- void close():关闭输入流对象,释放空间
4.2OutputStream
表示字节输出流的所有类的父类,输出流接受输出字节并发送到dest
4.2.1常用方法
- void write(int n):向目的地中写入一个字节。
- void close(:关闭输出流对象,释放相关系统资源。
4.3Reader
用于读取的字符流抽象类,数据单位为字符。
- int read():读取一个字符的数据,并将字符的值作为int
类型返回[0-65535]之间的一个值,即Unicode值)。如果未读出字符则返回-1(返回值为-1表示读取结束〕。 - void close():关闭流对象。释放相关系统资源,
4.4Writer
writer用于输出的字符流抽象类,数据单位为字符。
- void write(int n):向输出流中写入一个字符。
- void close() :关闭输出流对象,释放相关系统资源。
5.Java中流的概念细分
5.1流按方向分为输入流和输出流
- 输入流:数据流从数据源到程序(以InputStream、Reader结尾的流)
- 输出流:数据流从程序到目的地(以Output Stream、Writer结尾的流)
5.2按照处理的数据单元分类分为字节流和字符流
- 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流。例:FileInputStream、FileInputStream。
- 字符流:一字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字节流。例:FileReader、FileWriter。
5.3按照处理对象分为节点流和处理流
- 节点流:可以直接从数据源或目的地读取数据,例:FileInputStream、FileReader、DateInputStream。
- 处理流:不直接连接数据源或目的地,是“处理流的流”。通过对其他流的处理提高程序的性能。例:BufferedInputStream、BufferedReader等,处理流也叫包装流。
6.Java中IO流的体系
- 常用目录
- InputStream/OutputStream
字节流的抽象类。 - Reader/Writer
字符流的抽象类。 - FilelnputStream/FileOutputStream
节点流:以字节为单位直接操作"文件". - ByteArrayinputStream/ByteArrayOutputStream
节点流:以字节为单位直接操作“字节数组对象”。 .ObjectinputStream/ObjectOutputStream
处理流:以字节为单位直接操作*对象". - DatalnputStream/DataOutputStream
处理流:以字节为单位直接操作*基本数据类型与字符串类型". - FileReader/FileWriter
节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件). - Bufferedisader/Bufferedfbriter
处理流:将Reader/Writer对象进行包装。增加缓存功能,提高读写效率。 - BufferedllnputStream/BufferedOutputStream
处理流:将lnputStream/OutputStream对象进行包装,增加缓存功能,提高
读写效率。 - lnputStreamReader/OutputStreamWriter
处理流:将字节流对象转化成字符流对象。 - PrintStream
处理流:将OutputStream进行包装。可以方便地输出字符,更加灵活。
二、简单实例
public static void main (string[] args) {
FileInputstream fis = null;
try{
//创建字节输入流对象
fis = new FileInputstream ("d: /a.txt");//
int sl = fis.read() ;//打印输入字符a对应的ascii码值
int s2 = fis.read();//打印输入字符b对应的ascii码值
System. out.println (s1) ;
System. out.println (s2) ;
}catch (Exception e){
e.printstackTrace () ;
}finally {
if(fis != nul1){
try {
fis.close() ;
} catch (Exception e){
e.printstackTrace() ;
}
}
}/*
只能一个个读取*/
}
}
改进之后
public static void main (string[] args){
FileInputstream fis = null;
try {
//创建字节输入流对象
fis = new FileInputStreamn ( name: "d: /a.txt" );
StringBuilder sb = new StringBuilder();
int temp = 0;
while ( (temp = fis.read()) != -1) {
system.out.println (temp) ;
sb.append((char)temp);
}
System.out.println(sb.toString());
}catch (Exception e){
e.printStackTrace ( ) ;
}finally {
if(fis != nul1){
try {
fis.close() ;
} catch (Exception e){
e.printstackTrace() ;
}
}
}
三、File的使用
1.File类简介
1.1File类的作用
Java提供的争对磁盘中文件/目录转换对象的包装类。File对象可以代表文件,可以实现获取文件/目录属性,并可以创建和删除等
1.2File类作用目录与文件常用方法
1.2.1文件的操作方法
- createNewFile()//创建新文件。
- delete()//直接从磁盘上删除
- exists()//查询磁盘中的文件是否存
- getAbsolutePath(//获取绝对路径
- getPath(//获取相对路径
- getName()//获取文件名相当于调用了一个toString方法。
- isFile()//判断是否是文件
- length()//查看文件中的字节数
- isHidden(//测试文件是否被这个抽象路径名是一个隐藏文件。
1.2.2针对目录操作的方法
- exists()//查询目录是否存在
- isDirectory()//判断当前路径是否为目录
- mkdir()//创建目录
- getParentFile()//获取当前目录的父级目录
- list()//返回一个字符串数组,包含目录中的文件和目录的路径名。
- listFiles()//返回一个File数组,表示用此抽象路径名表示的目录中的文件。
2.File类基本使用
public static void main (String[] args ) throws Exception {
//创建file对象
File file = new File( pathname: "d:/aa .txt" ) ;
System.out.println (file.createNewFile ());
System.out.println (file.delete ());
System.out.println (file.exists());
System. out.println (file.getName () );
System.out.println (file.isFile()) ;
System.out.println (file.isHidden ());
}
}
public static void main (string[] args) {
//创建File对象
File file = new File( pathname: "d: /b/c") ;
// System.out.println (file.mkdir ( ) );
//System.out.println (file.mkdirs( ) );
// System.out.println (file.exists ( ) );
// System.out.println (file.isDirectory ());
//system.out.println(file.getParent();
//System.out.println(file.getParentFile () .getName ());
File file2 = new File ("d:/");
String[] arr = file2.list ();
for (String temp:arr){
System.out.println(temp);
}
System.out.println ("--------------------");
File[]arr2 = file2.listFiles();
for(File temp :arr2{
System.out.println(temp);
}
}
四、常用流对象
1.文件字节流
FileInputStream 通过字节的方式读取文件,适合读取所有类型的文件〔图像、视频、文
本文件等)。Java也提供了FileBeader专门读取文本文件。
FileOutputStrcam诵过字节的方式写数据到文件中,适合所有类型的文 件,Java_也提供
了FileWriter专门写入文本文件。
1.1文件字节输入流
public static void main (string[] args){
FileInputstream fis = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream ( name: "d: / sxt.jpg" ) ;int temp = 0;
while((temp = fis.read())!=-1){
System. out.println (temp) ;
}
} catch (Fxception e){
e.printstackTrace ();
} finally{
try{
if(fis != nul1){
fis.close () ;
}
}catch (Exception e) {
e.printstackTrace ();
}
1.2文件字节输出流```java
public static void main (string[] args){
FileInputstream fis = null;
FileOutputstream fos = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream ( name: "d: / sxt.jpg") ;
//创建文件字节输出流对象
fos = new FileOutputStream ( name: "d: / aa.jpg" ) ;
int temp = 0;
while((temp = fis.read())!=-1){
//System. out.println (temp) ;
fos.write(temp);
}
//写数据从内存中写入到磁盘
fos.flush();
} catch (Fxception e){
e.printstackTrace ();
} finally{
try{
if(fis != nul1){
fis.close () ;
}
if(fos != nul1){
fos.close ();
}
}catch (Exception e) {
e.printstackTrace ();
}//只能一个字节一个字节的操作
1.3通过缓冲区提高读写效率
1.3.1方法一
- 通过创建一个指定长度的字节数组作为缓冲区,以此来提高Io流的读写效率。该方式适用于读取较大图片时的缓冲区定义。注意:缓冲区的长度一定是2的整数幂。一般情况下 1024长度较为合适。
public static void main (string[] args) {
FileInputStream fis = null;
FileOutputstream fos = null;
try{
//创建文件字节输入流对象
fis = new FileInputStream ( name: "d: / itbz.jpg" );//创建文件字节输出流对象
fos = new Fileoutputstream ( name: "d:/cc.jpg" );//创建一个缓冲区,提高读写效率
byte[ ] buff = new byte [ 1024];
int temp = 0;
while ((temp = fis.read (buff))!= -1){
fos.write (buff,off: 0, temp) ;
}
//将数据从内存中写入到磁盘中。
fos.flush ( ) ;
}catch (Exception e){
e.printstackTrace () ;
} finally{
try {
if(fis != nul1){
fis.close();
}
if(fos != nu11){
fos.close ();
}
}catch (Exception e){
e.printstackTrace () ;
}
}
1.3.2法二
通过创建一个字节数组作为缓冲区,数组长度是通过输入流对象的 available()返回当前文件的预估长度来定义的。在读写文件时,是在一次读写操作中完成文件读写操作的。注意:如果文件过大,那么对内存的占用也是比较大的。所以大文件不建议使用该方法。
public static void main (string[] args) {
FileInputstream fis = null;
FileoutputStream fos = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream ( name: "d: / itbz.jPg" );
//创建文件字节输出流对象
fos = new Fileoutputstream ( name: "d: / cc.jpg" ) ;
//创建一个缓冲区,提高读写效率
byte[ ] buff = new byte[fis.available() ];
fis.read(buff);
//将数据从内存中写入到磁盘中。
fos.write (buff);
fos.flush () ;
try {
if(fis != nul1){
fis.close();
}
if(fos != nu11){
fos.close ();
}
}catch (Exception e){
e.printstackTrace () ;
}
}
1.4通过字节缓冲流提高读写效率
Java缓冲流本身并不具有Io流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。因此,缓冲流还是很重要的,我们在I0操作时记得加上缓冲流来提升性能。
BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。
public static void main (string[] args) {
FileInputstream fis = null;
FileoutputStream fos = null;
BufferedInputStream bis =null;
Bufferedoutputstream bos = null;
try {
fis = new FileInputStream ( name: "d: / itbz.jpg" );
bis = new BufferedInputstream(fisl;
fos = new Fileoutputstream ( name: "d : /ff .jpg" ) ;
bos = new BufferedOutputstream (fos) ;
int temp = 0;
while(temp = bis.read()!=-1){//byte默认长度8192
bos.write(temp);
}
} catch(Exception e){
e.printstackTrace ();
}finally{
try{
//注意:关闭流顺序:"后开的先关闭"
if (bis != null){
bis.close ( );
if(fis != null){
fis.close ();
if (bos !=null){
bos.close() ;
}
if( fos !=nul1){
fos.close() ;
}
} catch(Exception e){
e.printstackTrace () ;
}
1.5定义文件拷贝工具类
public class FileCopyTools {
public static void main (String[] args) {
copyFile( src: "d: /itbz.jpg" , des: "d: /abc.jpg" ) ;
)
/**
文件拷贝方法*/
public static void copyFile (String src,String des){
FileInputStream fis - null;
BufferedInputStream bis = null;
Fileoutputstream fos = null;
Bufferedoutputstream bos = null;
try{
bis = new BufferedInputstream(new FileInputStream (src));
bos = new BufferedOutputStream (new Fileoutputstream (des);
int temp = 0 ;
while( (temp = bis.read ()) != -1){
bos.write(temp);
}
bos.flush ();
} catch(Exception e){
e.printStackTrace ();
} finally{
try{
if (bis != nul1){
bis.close ();
}
if( fis != null){
fis.close ();
}
if(bos != nul1){
bos.close();
if( fos !=nul1){
fos.close() ;
}
} catch(Exception e){
e.printstackTrace () ;
}
2.文件字符流
文本文件可以使用文件字符流
2.1文件输入流
public static void main (string[] args) {
FileReader frd = null;
try{
//创建文件字符输入流对象
frd = new FileReader ( fileName: "d: /a.txt" );
int temp = 0;
while( (temp = frd.raad ()) != -1){
System.out.println ( (char) temp) ;
}
} catch (Exception e){
e.printStackTrace ( ) ;
} finally {
try {
if ( frd != nul1){
frd.close () ;
}
} catch(Exception e){
e.printStackTrace ();
}
}
}
2.2文件字符输出流
public static void main (String [] args){
Filewriter fw = null;
Filewriter fw2 = null;
try{
//创建字符输出流对象
fw = new Filewriter ( fileName: "d: / sxt.txt" );
fw.write ( str:"你好尚学堂\r\n" ) ;
fw.write ( str:"你好o1dlu\rin" ) ;
fw.flush ();
fw2.write ( str:"何以解忧\r\n唯有尚学堂");
fw2.flush ( );
} catch (Exception e){
e.printStackTrace ();
} finally(
try{
if(fw != null){
fw.close();
}
if (fw2 != null){
fw2.close ( ) ;
}catch (Exception e){
e.printStackTrace () ;
}
}
}
2.3使用字符流实现文本文件的拷贝处理
public static void main (string [] args){
FileReader fr = null;
Filewriter fw = null;try {
fr = new FileReader ( fileName: "d: /2.txt" ) ;
fw = new Filewriter( fileName: "d: / 3.txt" ) ;
char[ ] buffer = new char[1024[;
int temp = 0;
while((temp = fr.read (buffer))!= -1) {
fw.write (buffer, off: o, temp) ;
}
fw.flush ( ) ;
} catch(Exception e){
e.printStackTrace () ;
}finally{
try {
if(fr != nul1){
fr.close () ;
if(fw != null)[
fw.close ();
}catch (Exception e){
e.printstackTrace ();
}
}
}
3.字符缓冲流
BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率。
3.1字符输入流
BufferedReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取。
public static void main (String[] args){
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader ( fileName: "d: / sxt.txt" );
br = new BufferedReader (fr);
String temp = "";
while((temp = br.readLine()) != nul1){
System.out.println (temp) ;
}
}catch(Exception e) {
e.printstackTrace ( );
}finally {
try {
if (br !=null){
br.close () ;
}
if(fr != nul1){
fr.close () ;
}
} catch (Exception e) {
e.printStackTrace ( ) ;
}
}
}
3.2字符输出缓冲流
BufferedWriter是针对字符输出流的缓冲流对象,在字符输出缓冲流中可以使用newLine();方法实现换行处理。
public static void main (String [ ] args) {
Filewriter fw = null;
Bufteredwriter bw = null;
try {
fw = new Filewriter ( fileName: "d: / sxt2 . txt" );
bw = new Bufferedwriter(fw);
bw . write( str: "你好尚学堂");
bw.write ( str:"你好o1dlu" ) ;
bw.newLine();
bw . write ( str:"何以解忧");
bw .newLine ( ) ;
bw . write ( str:"唯有尚学堂");
bw .flush ( ) ;
} catch (Exception e){
e.printStackTrace ( ) ;
}finally{
try{
if(bw != nul1){
bw.close();
}
if(fw != nul1){
fw.close();
}
}
}catch (Exception e){
e.printstackTrace () ;
}
}
}
3.3通过字符缓冲流实现对文本文件的拷贝
public static void main (String [ ] args) {
copyFile( src: "d:/2.txt" , des: "d:/22.txt" ) ;}
/**
*基于字符流缓冲流实现文件拷贝
*/
public static void copyFile (String src ,String des){
BufferedReader br = null;
Bufferedwriter bw = null;
try {
br = new BufferedReader (new FileReader (src)) ;
bw = new Bufferedwriter (new Filewriter (des) ) ;
String temp = "";
while( (temp - br.readLine()) != nullyi
bw.write (temp) ;
bw.newLine ( ) ;
}
bw.flush ( );
} catch (Exception e){
e.printStackTrace ( ) ;
}finally {
if (br != nul1){
br.close();}
if (bw != nul1){
bw.close();
}
}catch (Exception e){
e.printstackTrace ();
}
}
3.4通过字符缓冲流为文件中的内容添加行号
public static void main (string[] args) {
BufferedReader br = null;
Bufferedwriter bw = null;
try{
br = new BufferedReader(new FileReader ( fileName: "d :/ sxt2)
bw = new BufferedWriter(new Filewriter ( fileName: "d: / sxt3)
String temp = "";
int i = l;
while ( (temp = br.readLine() )!= nul1) {
bw.write ( str:i+","+temp) ;
bw.newLine ( ) ;
i++;
bw.flush ( );
} catch (Exception e){
e.printStackTrace ( ) ;
}finally {
try{
if (br != nul1){
br.close();}
if (bw != nul1){
bw.close();
}
}catch (Exception e){
e.printstackTrace ();
}
}
}
4.转换流
4.1通过转换流实现键盘输入屏幕输出
lnputStreamReader/OutputStreamWriter 用来实现将字节流转化成字符流。
System.in是字节流对象,代表键盘的输入,如果我们想按行接收用户的输入时,就必须用到缓冲字符流BufferedReader特有的方法readLine(),但是经过观察会发现在创建BufferedReader的构造方法的参数必须是个Reader对象,这时候我们的转换流InputStreamReader就派上用场了。
而System.out也是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到 控制台,就需要用到字符流的write(String str)方法,所以我们要使用OutputStreamWriter将字节流转化为字符流。
public static void main (string[ ] args){
BufferedReader br = null;
Bufferedwriter bw = null;
try{
br = new BufferedReader (new InputstreamReader (System.in));
bw = new BulleredwriLer (new OutputStreamWriter(SysLem.out));
while (true) {
bw.write ( str:"请输入: ") ;
bw .flush ( ) ;
String input = br.readLine ( );
if ( "exit" .equals (input) ) {
break;
}
bw.write(str:"你输入的是:"+input);
bw .newLine ( ) ;
bw.flush () ;
}
} catch (Exception e){
e.printstackTrace ();
} finally{
try{
if(bw != nul1) {
bw.close() ;
if (br != nuli) {
br.close ( ) ;
}
} catch (Exception e){
e.printstackTrace ( );
}
}
}
4.2通过字节流读取文本并添加行号
public class LineNumberDemo2 {
public static void main (String[] args) {
BufferedReader br = null;
Bufferedwriter bw = null;
try{
br = new BufferedReader (new InputstreamReader (new FileInputStream("d :/ sxt.txt"));
bw = new Bufferedwriter (new OutputstreamWriter (new
FileOutputStream("d :/ sxt3.txt"));
String temp = "";
int i = 1;
while ( (temp = br.readLine() )!= nul1) {
bw.write ( str:i+","+temp) ;
bw.newLine ( ) ;
i++;
bw.flush ( );
} catch (Exception e){
e.printStackTrace ( ) ;
}finally {
try{
if (br != nul1){
br.close ( ) ;
}
if ( bw != null ) {
bw.close () ;
} catch (Exception e){
e.printStackTrace ( );
}
}
}
5.字符输出流
在Java的lo流中专门提供了用于字符输出的流对象PrintWriter。该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可通过println();方法实现自动换行。
public static void main (string [] args) {
BufferedReader br = null;
Printwriter pw = null;
try{
br = new BufferedReader (new InputStreamReader (new FileInputStream("d :/ sxt.txt"));
pw = new Printwriter ( fileName: "d: / sxt4.txt" ) ;
string temp ="";
int i = 1;
while ( (temp = br.readLine() )!= nul1) {
pw.write (i+","+temp) ;
i++;
}
} catch (Exception e) {
e.printStackTrace () ;
}finally {
try {
if (br != nul1){
br.close () ;
}
if(pw != null){
pw.close ( ) ;
}
} catch(Exception e){
e.printStackTrace ( );
}
}
}
6.字节数组流
- ByteArrayInputStream和 ByteArrayOutputStream经常用在需要流和数组之间转化的情况!
6.1字节数组输入流
FilelnputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”字节数组对象"当做数据源。
public static void main (String[] args) {
byte[] arr = "abcdefg".getBytes ( );
ByteArrayInputstream bis = null;
StringBuilder sb = new stringBuilder ( );
try {
//该构造方法的参数是一个字节数组,这个字节数组就是数据源
bis = new ByteArrayInputStream (arr) ;
int temp = 0;
while ( (temp = bis.read () )!= -1){
sb.append ( (char) temp);
}finally{
try {
bis.close ( );
} catch(Exception e){
e.printStackTrace ( ) ;
}
}
}
6.2字节数组输出流
ByteArravOutputStream流对象是将流中的数据写入到字节数组中。
public static void main (string [] args) {
ByteArrayoutputstream bos = null;
try{
StringBuilder sb = new stringBuilder ( ) ;
bos = new ByteArrayoutputstream ( ) ;bos.write ( b: 'a') ;
bos.write( b: 'b') ;
bos. write ( b: 'c');
byte[] arr = bos.toByteAgray ();
for(int i=0; i<arr.length;i++){
sb.append ((char) arr[i] );
}
system.out.println (sb.toString ( ) );
} finally {
try{
if(bos !=null){
bos.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
7.数据流
数据流将“基本数据类型与字符串类型"作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。DatalnputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据
7.1数据输出流
public static void main (String[] args) {
DataOutputstream dos = null;
try{
dos=new Dataoutputstream(new BufferedoutputStream(newFileOutputstream ( name: "d:/data.txt")));
dos.writechar ( "a ' );
dos.writeInt ( 10);
dos.writeDouble(Math. random() );
dos.writeBoolean ( v: true) ;
dos.writeUTF ( str“你好尚学堂");
dos.flush () ;
}catch (Exception e) {
e.printstackTrace ( ) ;
}finally{
try{
if (dos != null){
dos.close ( ) ;
}
}catch(Exception e) {
eprintStackTrace();
}
}
}
7.2数据输入流
public static void main (String[ ] args) {
DataInputstream dis = null;
try {
dis =new DataInputstream(new BufferInputStream(new FileInputStream("d:/data.txt"")));
//直接读取数据,读取顺序要和写入一致
system. out.println ( "char: "+dis.readChar ());
system.out.println ( "int: "+dis.readInt ()) ;
system.out.println ( "double : r "+dis.readDouble ()) ;
system.out.println ( "boolean : "+dis.readBoolean ()) ;
system.out.println ( "string: "+dis.readUTF()) ;
} catch (Exception e){
e.printstackTrace ( ) ;
} finally{
try {
if(dis != null ) {
dis.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
8.对象流
- 对象的本质是用来组织和存储数据的,对象本身也是数据。我们可以通过序列化和反序列化来实现这些需求。
8.1Java对象序列化和反序列化
8.1.1 基本概念
当两个进程远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。比如,我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送lJava对象。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常读取。
- 把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的 过程称为对象的反序列化。
对象序列化的作用有两种:
- 持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中.
- 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传 递。
8.1.2序列化涉及的类和接口
-
objectOutputstream代表对象输出流,它的writeobjecti(Object obj)方法可对参数指定的
obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 -
objectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节 序列,再把它们反序列化为一个对象,并将其返回。
-
只有实现了5erializable接口的类的对象才能被序列化。Serializable接口是一个空接口, 只起到标记作用,。 I
8.2操作基本数据类型
数据流只能实现对基本数据类型和字符串类型的读写,并不能对Java对象进行读写操作(字符串除外),对象流则可以!
8.2.1写出基本数据类型数据
public static void main (string [] args) {
Objectoutputstream oos = null;
try {
oos = new 0bjectOutputStream (new Bufferedoutputstream (new FileOutputStream("d:/xxt5")));
oos.writeInt ( val: 10) ;
oos.writeDouble (Math. random ());
oos.writeChar ( val: 'a ' ) ;
oos.writeBoolean ( val: true) ;
oos.writeUTF ( str: "你好o1dlu" );
oos.flush ( );
} catch (Exception e)f
e.printstackTrace();
}finally {
try {
if(oos ! = null){
oos.close ( ) ;
}
} catch (Exception e ) {
e.printstackTrace ( );
}
}
}
8.2.2读取基本数据类型数据
public static void main (string [] args) {
objectInputstream ois = null;
try {
ois = new 0bjectInputStream (new BufferedInputStream (new FileInputStream("d:/xxt5")));
//必须要按照写入的顺序读取数据
System.out.println ( "int: "+ois.readInt () );
System.out.println ( "double: "+ois.readDouble( ));
System.out.println ( "char: "+ois.readChar () );
System.out.println ( "boolean : "+ois.readBoolean ()) ;
System.out.println ( "String: "+ois.readUTF());
} catch (Exception e){
e.printstackTrace ( ) ;
}finally {
try {
if(ois ! = null){
ois.close () ;
}
} catch (Exception e ) {
e.printstackTrace ( );
}
}
}
8.3操作对象
8.3.1将对象序列化到文件
ObjectOutputStream可以将一个内存中的Java对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable 序列化接口,否则会抛出异常。
8.3.1.1创建对象
public class Users implements Serializable{
private int userid;
private string username ;
private String userage;
public Users(int userid,String username,string userage){
this.userid = userid;
this.username = username;
this.userage = userage;
}
public String getUsername ( ){
return username;
}
public void setUsername ( String username) {
this.username = username ;
}
public String getUserage(){
return userage;
public void setUserage (string userage) {
this.userage = userage;
}
}
8.3.1.2序列化对象
public static void main (string [] args) {
ObjectOutputStream oos = null;
try{
oos = new 0bjectOutputstream (new Fileoutputstream ( name: "d: / sxt6.txt);
Users users = new Users ( userid: 1, username: "oldlu",userage:"18");
oos. writeObject (users);
oos.flush ( ) ;
}catch (Exception e){
e.printStackTrace ( ) ;}finally {
try {
if (oos != null){
oos.close () ;
}
} catch (Exception e){
e.printstackTrace ();
8.3.2 将对象反序列化到内存
public static void main (string[] args) {
objectInputstream ois = null;
try {
ois = new 0bjectInputstream (new FileInputstream ( name: "d:/sk.txt"));
Users users = (Users)ois.readObject ( ) ;
System.out.println (users.getUserid () +"\t"+users.getUsername () +"\t"+users.getUserage () );
} catch (Exception e) {
e.printstackTrace () ;
} finally{
try {
if (ois != null){
ois.close ( );
}catch (Exception e){
e.printstackTrace ( );
}
}
}
9.随机访问流
RandomAccessFile可以实现两个作用:
- 实现对一个文件做读和写的操作。
- 可以访问文件的任意位置。不像其他流只能按照先后顺序读取。
学习这个流我们需掌握三个核心方法:
- RandomAccessFile(String name,String mode) name用来确定文件; mode
取r(读)或rw(可读写),通过mode可以确定流对文件的访问权限。 - seek(long a)用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数。
- getFilePointer()获得流的当前读写位置。
public static void main (String[] args) {
RandomAccessFile raf = null;
try{
raf = new RandomAccessFile (name: "d: /sxt7.txt" , mode: "rw")//将若干数据写入到文件中
int[] arr = new int[] { 10,20,30,40,50,60,70,80,90,100};
for (int i=0; i<arr.length; i++){
raf.writeInt (arr[i]);
}
raf.seek ( poS: 4) ;
System.out.println (raf.readInt () );
//隔一个读一个数据
for(int i=0;i<10; i+=2){
raf.scck ( pos: i*4);
System.out.print (raf.readInt ()+"\t" ) ;
}
System.out.println();
//在第8个字节位置插入一个新的数据45,替换之前的数据30raf.seek ( pos: 8) ;
raf.writeInt(v 45);
for(int i=0;i<10; i+=2){
raf.seek ( pos:i*4);
System.out.print (raf.readInt ( )+"\t");
}catch (Exception e){
e.printStackTrace () ;
}finally {
try{
if (raf != null){
raf.close ();
}catch (Exception e){
e.printstackTrace ( );
}
}
}
10.File类在IO中的作用
当以文件作为数据源或目标时,除了可以使用字符串作为文件以及位置的指定以外,我
们也可以使用File类指定。
public static void main (String[] args) {
BufferedReader br = null;
Bufferedwriter bw = null;
try{
br = new BufferedReader(new FileReader(new File( pathname:
bw = new Bufferedwriter(new Filewriter (new File ( pathname:
String temp = "";
int i =1;
while ((temp = br.readLine() ) != nul1) {
bw .write ( str:i+", " +temp);
bw .newLine () ;
i++;
}
bw.flush ();
} catch (Exception e){
e.printStackTrace () ;
}finally{
try{
if(br != nul1){
br.close ();
}
}catch(Exception e)
e.printstackTrace ( );
}
}
}
五、Apache IO包
下载直接搜索就行,到入也可
方法在API文档中
FileUitls的使用一
public class FileUtilsDemol {
public static void main (string[] args) throws Exception {
String content =FileUtils.readEileTostring (new
File ( "d: / sxt.txt" ), "utf-8");
system.out.println (content ) ;
}
}
FileUitls的使用二
public static void main (String[] args ) throws Exception {
FileUtils.copyDirectory(new File ( pathname: "d:/a" ), new File( "c:/a" ),new FileFilter){
//在文件拷贝时的过滤条件
public boolean accept ( File pathname) {
if (pathname.isDirectory()||pathname.getName ( ) .endswith ( "htm1" ) ){
return true;
}
return false ;
});
}
}
IOUitls的使用
public class IoUtilsDemo {
public static void main (String[ ] args)throws Exception {
String content - IOUtils.tostring (new
FileInputstream ( "d: / sxt.txt"),"utf-8" ) ;
system.out.println (content ) ;
)