目录
Ios流专项
一、Io简介
1、什么是IO
对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等等。外部系统比较复杂多变,那么我们有必要通过某种手段进2行抽象、屏蔽外部的差异,从而实现更加便捷的编程。
2、数据源
3、流的概念
4、Java中四大IO抽象类
InputStream/OutputStream和Reader/Writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用。然后,通过它们具体的子类熟悉相关的用法。
InputStream:
此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽象类,它不可以实例化。数据的读取需要由它的子类来实现。根据节点的0
.0不同,它派生了不同的节点流子类。
继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8bit)。
OutputStream:
此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地。
Reader:
Reader用于读取的字符流抽象类,数据单位为字符。
Write:
5、Java中流的概念细分
6、Java中IO流类的体系
Java为我们提供了多种多样的IO流,我们可以根据不同的功能及性能要求挑选合适的IO流。
File和RandomAccessFile不属于IO体系中的类
从上图发现,很多流都是成对出现的,比如:FileInputStream/FileOutputStream,显然是对文件做输入和输出操作的。下面简单做个总结:
二、IO流入门案例
1、第一个简单的IO流程序
package IO流;
import java.io.FileInputStream;
public class FirstDemo {
public static void main(String[] args) {
//创建字节输入流对象
FileInputStream fis=null;
try {
fis=new FileInputStream("D:/a.txt");
//read方法读取文件时是一个一个字符读取的
int s1=fis.read();//打印输出字符a对应的ascii值97
int s2=fis.read();//打印输出字符b对应的ascii值98
int s3=fis.read();//打印输出字符c对应的ascii值99
int s4=fis.read();//由于文件内容已经读完,则返回-1
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(fis!=null){
try {
fis.close();//关闭流对象
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
2、改造入门案例
package IO流;
import java.io.FileInputStream;
public class SecondDemo {
public static void main(String[] args) {
FileInputStream fis=null;
{
try {
fis = new FileInputStream("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);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fis!=null) {
fis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
三、File类的使用
1、File类的简介
1.1File类的作用
File类是Java提供的针对磁盘中的文件或目录转换对象的包装类。一个File对象而可以代表一个文件或目录,File对象可以实现获取文件和目录属性等功能,可以实现对文件和目录的创建,删除等功能。
1.2File类操作目录与文件的常用方法
2、File类的基本使用
2.1 操作文件
package IO流;
import java.io.File;
public class FileDemo {
public static void main(String[] args) throws Exception {
//创建File对象
File file=new File("D:/aa.txt");//使用file都相当于对该文件进行操作
System.out.println(file.createNewFile());
//System.out.println(file.delete());
System.out.println(file.exists());
System.out .println(file.getAbsolutePath());
System.out .println(file.getPath());
System.out.println(file.getName());
System.out.println(file.isFile());
System.out.println(file.isHidden());
}
}
2.2 操作目录
package IO流;
import java.io.File;
public class DirectoryDemo {
public static void main(String[] args) {
//File file=new File("D:/a");
//System.out.println(file.mkdir());//创建单级目录
File file2=new File("D:/b/c");
//System.out.println(file2.mkdirs());//创建多级目录
//System.out.println(file2.isDirectory());
System.out.println(file2.getParent());//返回父级目录
File file3=new File("D:/");
String str[]=file3.list();//返回文件名
for(String temp:str){
System.out.println(temp);
}
System.out.println("------------------");
File str2[]=file3.listFiles();//会返回绝对路径
for(File temp:str2){
System.out.println(temp);
}
}
}
四、常用流对象
1、文件字节流
1.1 文件字节输入流
package IO流;
import java.io.FileInputStream;
public class FileStreamDemo {
public static void main(String[] args) {
FileInputStream fis=null;
try {
//创建文字字节输入流对象
fis=new FileInputStream("D:/dulante1.jpg");
int temp=0;
while((temp=fis.read())!=-1){
System.out.println(temp);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fis!=null){
fis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1.2 文件字节输出流
package IO流;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamDemo {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//创建文字字节输入流对象
fis=new FileInputStream("D:/dulante1.jpg");
//创建文字字节输出流对象
fos=new FileOutputStream("D:/aa.jpg");
int temp=0;
while((temp=fis.read())!=-1){
fos.write(temp);
}
fos.flush();//将数据从内存中写入到磁盘中
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fis!=null){
fis.close();
}
if(fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1.3 通过缓冲区提高读写效率
package IO流;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamDemo {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//创建文字字节输入流对象
fis=new FileInputStream("D:/dulante1.jpg");
//创建文字字节输出流对象
fos=new FileOutputStream("D:/ab.jpg");
//创建一个缓冲区,提高读写效率
byte buff[]=new byte[1024];
int temp=0;
while((temp=fis.read(buff))!=-1){
fos.write(buff,0,temp);
}
fos.flush();//将数据从内存中写入到磁盘中
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fis!=null){
fis.close();
}
if(fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
package IO流;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamBuffer2Demo {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//创建文字字节输入流对象
fis=new FileInputStream("D:/dulante1.jpg");
//创建文字字节输出流对象
fos=new FileOutputStream("D:/ab.jpg");
//创建一个缓冲区,提高读写效率
byte buff[]=new byte[fis.available()];
fis.read(buff);
fos.write(buff);
fos.flush();//将数据从内存中写入到磁盘中
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fis!=null){
fis.close();
}
if(fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1.4 通过字节缓冲流提高读写效率
Java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。
因此,缓冲流还是很重要的,我们在IO操作时记得加上缓冲流来提升性能。
BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。
package IO流;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStringBuffered3Demo {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos= null;
try {
fis=new FileInputStream("D:/dulante1.jpg");
bis=new BufferedInputStream(fis);
fos=new FileOutputStream("D:/ff.jpg");
bos=new BufferedOutputStream(fos);
//缓冲流中的byte数组长度默认是8192
int temp=0;
while((temp=bis.read())!=-1){
bos.write(temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
//关闭流对象时,后开的先关
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if(fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1.5 定义文件拷贝工具类
package IO流;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopyTools {
public static void main(String[] args) {
copyFile("D:/dulante1.jpg","D:/abc.jpg");
}
/**
* 文件拷贝方法
*/
//定义内部静态方法之后可以直接使用方法名,不需要实例化
public static void copyFile(String src,String des) {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(src));
bos = new BufferedOutputStream(new FileOutputStream(des));
//缓冲流中的byte数组长度默认是8192
int temp = 0;
while ((temp = bis.read()) != -1) {
bos.write(temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭流对象时,后开的先关
if (bis != null) {
bis.close();
}
if (fis != null) {
fis.close();
}
if (bos != null) {
bos.close();
}
if (fos != null) {
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
2、文件字符流
前面介绍的文件字节流可以处理所有的文件,如果我们处理的是文本文件,也可以使用文件字符流,它以字符为单位进行操作。
2.1文件字符输入流
package IO流;
import java.io.FileReader;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader frd=null;
try {
//创建文件字符流输入流对象
frd=new FileReader("D:/a.txt");
int temp=0;
while((temp=frd.read())!=-1){
System.out.println((char)temp);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(frd!=null){
frd.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.2文件字符输出流
package IO流;
import java.io.FileWriter;
public class FileWriterDemo {
public static void main(String[] args) {
FileWriter fw=null;
FileWriter fw2=null;
try {
//创建字符输出流对象
fw= new FileWriter("D:/aa.txt");
fw.write("java\r\n");//\r\n回车换行
fw.write("好难");
fw.flush();//刷新
//多个FileWriter操作同一个对象,默认进行覆盖
fw2=new FileWriter("D:/aa.txt",true);//第二个参数给true是追加操作,那么就不会进行覆盖,直接在末尾添加
fw2.write("难");
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 使用字符流实现文本文件的拷贝处理
package IO流;
import java.io.FileReader;
import java.io.FileWriter;
public class FileCopyTools2 {
public static void main(String[] args) {
FileReader fr=null;
FileWriter fw=null;
try{
fr=new FileReader("D:/a.txt");
fw=new FileWriter("D:/b.txt");
int temp=0;
char buffer[]=new char[1024];
while((temp=fr.read(buffer))!=-1){
fw.write(buffer,0,temp);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(fr!=null){
fr.close();
}
if(fw!=null){
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3、字符缓冲流
3.1 字符输入缓冲流
BufferedReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取。
package IO流;
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReaderDemo {
public static void main(String[] args) {
FileReader fr=null;
BufferedReader br=null;
try {
fr=new FileReader("D:/aa.txt");
br=new BufferedReader(fr);
String temp="";
while((temp=br.readLine())!=null){//字符串是null,int类型是-1
System.out.println(temp);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(br!=null){
br.close();
}
if(fr!=null){
fr.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.2 字符输出缓冲流
BufferedReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取。
package IO流;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferedWriterDemo {
public static void main(String[] args) {
FileWriter fw=null;
BufferedWriter bw=null;
try {
fw=new FileWriter("D:/c.txt");
bw=new BufferedWriter(fw);
bw.write("好难的java");
bw.write("真的难");
bw.newLine();//实现换行处理
bw.write("...");
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bw!=null){
bw.close();
}
if(fw!=null){
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.3 通过字符缓冲流实现文本文件的拷贝
package IO流;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class FileCopyTools3 {
public static void main(String[] args) {
copyFile("D:/a.txt","D:/d.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())!=null){
bw.write(temp);
bw.newLine();//读取是按行,但是写入不是,要自己加newLine
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.4通过字符缓冲流为文件中的内容添加行号
package IO流;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class LineNumberDemo {
public static void main(String[] args) {
BufferedWriter bw=null;
BufferedReader br=null;
try {
br=new BufferedReader(new FileReader("D:/aa.txt"));
bw=new BufferedWriter(new FileWriter("D:/e.txt"));
String temp="";
int i=1;
while((temp=br.readLine())!=null){
bw.write(i+"、"+temp);
bw.newLine();
i++;
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bw!=null){
bw.close();
}
if(br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
4、转换流
4.1 通过转换流实现键盘输入到屏幕的输出
package IO流;
import java.io.*;
public class ConvertStream {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try{
br=new BufferedReader(new InputStreamReader(System.in));
bw=new BufferedWriter(new OutputStreamWriter(System.out));
while(true){
bw.write("请输入:");
bw.flush();
String input=br.readLine();
if("exit".equals(input)) {
break;
}
bw.write("你输入的是:" + input);
bw.newLine();
bw.flush();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (bw!=null){
bw.close();
}
if(br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
4.2 通过字节流读取文本文件并添加行号
package IO流;
import java.io.*;
public class LIneNumberDemo2 {
public static void main(String[] args) {
BufferedWriter bw=null;
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream("D:/a.txt")));
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:/f.txt")));
String temp="";
int i=1;
while((temp=br.readLine())!=null){
bw.write(i+", "+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bw!=null){
bw.close();
}
if(br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
5、字符输出流
在Java的IO流中专门提供了用于字符输出的流对象PrintWriter。该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可通过println();方法实现自动换行。
package IO流;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStringBuffered3Demo {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos= null;
try {
fis=new FileInputStream("D:/dulante1.jpg");
bis=new BufferedInputStream(fis);
fos=new FileOutputStream("D:/ff.jpg");
bos=new BufferedOutputStream(fos);
//缓冲流中的byte数组长度默认是8192
int temp=0;
while((temp=bis.read())!=-1){
bos.write(temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
//关闭流对象时,后开的先关
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if(fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
6、字节数组流
ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况!
6.1 字节数组输入流
说白了,FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”字节数组对象”当做数据源。
package IO流;
import java.io.ByteArrayInputStream;
public class ByteArrayInputDemo {
public static void main(String[] args) {
byte arr[]="abcdefg".getBytes();
StringBuilder sb=new StringBuilder();
ByteArrayInputStream bis=null;
try {
//该构造方法的参数是一个字节数组,这个字节数组就是数据源
bis=new ByteArrayInputStream(arr);
int temp=0;
while((temp=bis.read())!=-1){
sb.append((char)temp);
}
System.out.println(sb.toString());
}finally {
try {
bis.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
6.2 字节数组输入流
ByteArrayOutputStream流对象是将流中的数据写入到字节数组中。
package IO流;
import java.io.ByteArrayOutputStream;
public class ByteArrayOutputDemo {
public static void main(String[] args) {
ByteArrayOutputStream bos=null;
StringBuilder sb=new StringBuilder();
try {
bos=new ByteArrayOutputStream();
bos.write('a');
bos.write('b');
bos.write('c');
byte arr[]=bos.toByteArray();
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基本数据类型与字符串类型。
DataInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据(如:int、double、String等)的方法。
7.1 数据输出流
package IO流;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutputDemo {
public static void main(String[] args) {
DataOutputStream dos=null;
try {
dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/bb.txt")));
dos.writeChar('a');
dos.writeInt(10);
dos.writeDouble(Math.random());
dos.writeBoolean(true);
dos.writeUTF("好难的java");
dos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(dos!=null){
dos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
7.2 数据输入流
package IO流;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
public class DataInputDemo {
public static void main(String[] args) {
DataInputStream dis=null;
try {
dis=new DataInputStream(new BufferedInputStream(new FileInputStream("D:/bb.txt")));
//直接读取数据,注意:读取的顺序一定要和写入的顺序一致,否则无法正确读取数据
System.out.println("char: "+dis.readChar());
System.out.println("int: "+dis.readInt());
System.out.println("double: "+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.1 Java 对象的序列化和反序列化
8.2 操作基本数据类型
我们前边学到的数据流只能实现对基本数据类型和字符串类型的读写,并不能对Java对象进行读写操作(字符串除外),但是在对象流中除了能实现对基本数据类型进行读写操作以外,还可以对Java对象进行读写操作。
8.3 写出基本数据类型数据
package IO流;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("D:/d.txt")));
oos.writeInt(10);
oos.writeDouble(Math.random());
oos.writeChar('a');
oos.writeBoolean(true);
oos.writeUTF("好难的java");
oos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(oos!=null){
oos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
8.4 读取基本数据类型数据
package IO流;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new BufferedInputStream(new FileInputStream("D:/d.txt")));
//按照写入的顺序读取
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.5 操作对象
将对象序列化到文件:
ObjectOutputStream可以将一个内存中的Java对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序列化接口,否则会抛出异常。
package IO流;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new BufferedInputStream(new FileInputStream("D:/d.txt")));
//按照写入的顺序读取
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();
}
}
}
}
将对象反序列化到内存中:
package IO流;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStreamObjectTypeDemo {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new FileInputStream("D:/e.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、随机访问流
package IO流;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) {
RandomAccessFile raf=null;
try {
raf=new RandomAccessFile("D:/a.txt","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(4);//int类型是4个字节,因此要注意seek指针要4个一移动才能读到数据
System.out.println(raf.readInt());
raf.seek(4);//注意:每一次seek调用时,都是从0号位置开始指定跳跃,而不是从当前位置
System.out.println(raf.readInt());
System.out.println(raf.readInt());//会接着上面的指针继续读
System.out.println(raf.readInt());
//实现隔一个读一个数据
for(int i=0;i<10;i+=2){//10,30,50,70,90
raf.seek(i*4);
System.out.print(raf.readInt()+"\t");
}
System.out.println(raf.readInt());//指针已经在90的位置,再读一个读出100
//替换一个数据
raf.seek(8);//调节指针
raf.writeInt(45);//会直接替换掉原来的数据
for(int i=0;i<10;i+=2){//10,30,50,70,90
raf.seek(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类指定。
package IO流;
import java.io.*;
public class FileInIODemo {
public static void main(String[] args) {
BufferedWriter bw = null;
BufferedReader br = null;
try {
br=new BufferedReader(new FileReader(new File("D:/aa.txt")));
bw=new BufferedWriter(new FileWriter(new File("D:/g.txt")));
String temp="";
int i=1;
while((temp=br.readLine())!=null){
bw.write(i+", "+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bw!=null){
bw.close();
}
if(br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
五、Apache IO包
JDK中提供的文件操作相关的类,但是功能都非常基础,进行复杂操作时需要做大量编程工作。实际开发中,往往需要你自己动手编写相关的代码,尤其在遍历目录文件时,经常用到递归,非常繁琐。Apache-commons工具包中提供了IOUtils/FileUtils,可以让我们非常方便的对文件和目录进行操作。本文就是让大家对IOUtils/FileUtils类有一个全面的认识,便于大家以后开发与文件和目录相关的功能。
ApacheIOUtils和FileUtils类库为我们提供了更加简单、功能更加强大的文件操作和IO流操作功能。非常值得大家学习和使用。
1、Apache 基金会介绍
Apache软件基金会(也就是ApacheSoftwareFoundation,简称为ASF),是专门为支持开源软件项目而办的一个非盈利性组织。在它所支持的Apache项目与子项目中,所发行的软件产品都遵循Apache许可证(ApacheLicense)。官方网址为:www.apache.org。
很多著名的Java开源项目都来源于这个组织。比如:commons、kafka、lucene、maven、shiro、struts等技术,以及大数据技术中的:hadoop(大数据第一技术)、hbase、spark、storm、mahout等。
2、下载与添加commons-io包
2.1 下载地址
(现在已经到12了,直接去Apache官网搜索)
2.2 添加jar包
3、FileUtils 的使用
3.1 FileUtils的使用一:
package IO流;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class FileUtilsDemo1 {
public static void main(String[] args) throws IOException {
String content=FileUtils.readFileToString(new File("D:/aa.txt"),"utf-8");
System.out.println(content);
}
}
3.2 FileUtils的使用二:
package IO流;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileFilter;
public class FileUtilsDemo2 {
public static void main(String[] args) throws Exception {
FileUtils.copyDirectory(new File("D:/a"), new File("D:/c"), new FileFilter() {
//new了接口,必须跟上匿名内部类
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory()||pathname.getName().endsWith("html")){
return true;
}
return false;
}
});
}
}
4、IOUtils的使用
package IO流;
import org.apache.commons.io.IOUtils;
import java.io.FileInputStream;
public class IOUtilsDemo {
public static void main(String[] args) throws Exception {
String content= IOUtils.toString(new FileInputStream("D:/aa.txt"),"utf-8");
System.out.println(content);
}
}
六、本章总结
按流的方向分类:
输入流:数据源到程序(InputStream、Reader读进来)。
输出流:程序到目的地(OutPutStream、Writer写出去)。
按流的处理数据单元分类:
字节流:按照字节读取数据(InputStream、OutputStream)。
字符流:按照字符读取数据(Reader、Writer)。
按流的功能分类:
节点流:可以直接从数据源或目的地读写数据。
处理流:不直接连接到数据源或目的地,是处理流的流。通过对其他流的处理提高程序的性能。
IO的四个基本抽象类:InputStream、OutputStream、Reader、Writer
InputStream的实现类:
FileInputStream
ByteArrayInutStream
BufferedInputStream
DataInputStream
ObjectInputStream
OutputStream的实现类:
FileOutputStream
ByteArrayOutputStream
BufferedOutputStream
DataOutputStream
ObjectOutputStream
PrintStream
Reader的实现类
FileReader
BufferedReader
InputStreamReader
Writer的实现类
FileWriter
BufferedWriter
OutputStreamWriter
把Java对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为Java对象的过程称为对象的反序列化。