IO流
一、IO简介
1.什么是IO
输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是"读”,读取外部数据)。
常见的应用:
- 读取硬盘上的文件内容到程序。例如∶播放器打开一个视频文件、word打开一个doc文件。
- 读取网络上某个位置内容到程序。例如:浏览器中输入网址后,打开该网址对应的网页内容;下载网络上某个网址的文件。
- 读取数据库系统的数据到程序。
- 读取某些硬件系统数据到程序。例如:车载电脑读取雷达扫描信息到程序;温控系统等。
输出(Output)指的是:程序输出数据给外部系统从而可以操作外部系统(核心含义是“写”,将数据写出到外部系统)。
常见的应用有:
- 将数据写到硬盘中。例如∶我们编辑完一个word文档后,将内容写到硬盘上进行保存。
- 将数据写到数据库系统中。例如:我们注册一个网站会员,实际就是后台程序向数据库中写入一条记录。
- 将数据写到某些硬件系统中。例如:导弹系统导航程序将新的路径输出到飞控子系统,飞控子系统根据数据修正飞行路径。
java.io包为我们提供了相关的API,实现了对所有外部系统的输入输出操作
2.数据源
数据源Data Source,提供数据的原始媒介。常见的数据源有:数据库、文件、其他程序、内存、网络连接、IO设备。
数据源分为:源设备、目标设备。
- 源设备:为程序提供数据,一般对应输入流。
- 目标设备:程序数据的目的地,一般对应输出流。
3.流的概念
注意:输入/输出流的划分是相对程序而言的,并不是相对数据源。
4.Java中的四大IO抽象类
字节输入流:
字节输出流:
字符输入流:
字符输出流
5.Java中流的概念细分
按处理对象不同分类:
- 节点流:可以直接从数据源或目的地读写数据,如FilelnputStream、FileReader、DatalnputStream等。
- 处理流:不直接连接到数据源或目的地,是"处理流的流"。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。
6.Java中IO流类的体系
下图为Java中lo流类的体系(这里只列出常用的类,详情可以参考JDK API文档)
- 1.InputStream/OutputStream 字节流的抽象类。
- 2.Reader/Writer字符流的抽象类。
- 3.FilelnputStream/FileOutputStream 节点流:以字节为单位直接操作“文件”。
- 4.ByteArrayInputStream/ByteArrayOutputStream 节点流:以字节为单位直接操作“字节数组对象”。
- 5.ObjectInputStream/ObjectOutputStream 处理流:以字节为单位直接操作“对象”。
- 6.DatalnputStream/DataOutputStream 处理流:以字节为单位直接操作“基本数据类型与字符串类型”。
- 7.FileReader/FileWriter 节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件)。
- 8.BufferedReader/BufferedWriter 处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率
- 9.BufferedInputStream/BufferedOutputStream 处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写效率。
- 10.InputStreamReader/OutputStreamWriter 处理流:将字节流对象转化成字符流对象。
- 11.PrintStream 处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活。
二、IO流入门案例
1.第一个简单的IO流程序
import java.io.FileInputStream;
import java.io.IOException;
public class FirstDemo {
public static void main(String[] args) {
FileInputStream input=null;
try{
//创建字节输入流对象
input=new FileInputStream("d:/movies/a.txt");
StringBuilder sb=new StringBuilder();
int temp=0;
while(( temp=input.read())!=-1){
System.out.println(temp);//一次只能读文件一个字符,返回其ascii码值
sb.append((char)temp);
}
System.out.println(sb);
}catch(Exception e){
e.printStackTrace();
}finally{
if(input!= null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三、File类的使用
1.File类的作用
2.File类操作目录与文件的常用方法
- 1.针对文件操作的方法
createNewFile() //创建新文件。
delete() //直接从磁盘上删除
exists() //查询磁盘中的文件是否存在
getAbsolutePath() //获取绝对路径
getPath() //获取相对路径
getName() //获取文件名相当于调用了一个toString 方法。
isFile()//判断是否是文件
length()//查看文件中的字节数
isHidden()//测试文件是否被这个抽象路径名是一个隐藏文件。 - 2.针对目录操作的方法
exists()//查询目录是否存在
isDirectory()//判断当前路径是否为目录
mkdir()//创建目录
getParentFile()//获取当前目录的父级目录。
list()//返回一个字符串数组,包含目录中的文件和目录的路径名。
listFiles//返回一个File 数组,表示用此抽象路径名表示的目录中的文件。
3.file类的基本使用
/**
* 测试文件操作方法
*/
import java.io.File;
import java.io.IOException;
public class File_Demo1 {
public static void main(String[] args) throws IOException {
//创建File对象
File file=new File("d:/movies/aa.txt");
//创建文件
System.out.println(file.createNewFile());
//获取文件名字
System.out.println(file.getName());
//获取文件的相对路径
System.out.println(file.getPath());
//获取文件的绝对路径
System.out.println(file.getAbsolutePath());
//判断是否为文件
System.out.println(file.isFile());
//判断是否为隐藏文件
System.out.println(file.isHidden());
//删除文件
System.out.println(file.delete());
//判断file对象文件是否存在
System.out.println(file.exists());
}
}
/**
* 测试操作目录的方法
*/
import java.io.File;
public class Directory_Demo {
public static void main(String[] args) {
//创建File对象
File file1=new File("d:/movies/demo1");
//创建单级目录
System.out.println(file1.mkdir());
File file2=new File("d:/movies/demo2/a");
//创建多级目录
System.out.println(file2.mkdirs());
//判断文件是否存在
System.out.println(file2.exists());
//判断路径是否为目录
System.out.println(file2.isDirectory());
//获取父级目录
System.out.println(file2.getParent());
System.out.println(file2.getParentFile().getName());
//获取路径下所有的目录和文件
File file=new File("d:/movies");
String[] arr=file.list();//获取文件名和目录名
for(String str:arr){
System.out.println(str);
}
System.out.println("----------------");
File[] arr2=file.listFiles();//获取文件和路径的路径
for(File f:arr2){
System.out.println(f);
}
}
}
四、常用流对象文件字节流
1.文件字节流
/**
* 测试文件字节输入流
*/
import java.io.FileInputStream;
public class FileStream_Demo {
public static void main(String[] args) {
FileInputStream file=null;
try {
//创建文件字节输入流对象
file=new FileInputStream("d:/movies/QQ飞车.jpg");
int temp=0;
while((temp=file.read())!=-1){
System.out.println(temp);
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
if(file!=null){
file.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
/**
* 测试文件字节输入流和输出流
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStream_Demo {
public static void main(String[] args) {
FileInputStream file=null;
FileOutputStream fileout=null;
try {
//创建文件字节输入流对象
file=new FileInputStream("d:/movies/QQ飞车.jpg");
//创建文件字节输出流对象
fileout=new FileOutputStream("d:/movies/a.jpg");
int temp=0;
while((temp=file.read())!=-1){
fileout.write(temp);//读一个字节写一个字节
}
//将数据从内存中写入磁盘中
fileout.flush();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
if(file!=null){
file.close();
}
if(fileout!=null){
fileout.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
2.通过缓冲区提高读写效率
- 方式一
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamBuffer_Demo {
public static void main(String[] args) {
FileInputStream file=null;
FileOutputStream fileout=null;
try {
//创建文件字节输入流对象
file=new FileInputStream("d:/movies/QQ飞车.jpg");
//创建文件字节输出流对象
fileout=new FileOutputStream("d:/movies/aa.jpg");
//创建字节缓冲区,提高读写效率
byte[] buff=new byte[1024];
int temp=0;
while((temp=file.read(buff))!=-1){
fileout.write(buff, 0, temp);
}
//将数据从内存中写入磁盘中
fileout.flush();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
if(file!=null){
file.close();
}
if(fileout!=null){
fileout.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
- 方式二
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamBuffer_Demo2 {
public static void main(String[] args) {
FileInputStream file=null;
FileOutputStream fileout=null;
try {
//创建文件字节输入流对象
file=new FileInputStream("d:/movies/QQ飞车.jpg");
//创建文件字节输出流对象
fileout=new FileOutputStream("d:/movies/aaa.jpg");
//创建字节缓冲区,提高读写效率
byte[] buff=new byte[file.available()];//返回当前文件预估长度
//一次读写操作完成文件读写操作,不适用大文件,适合小文件
file.read(buff);
fileout.write(buff);
//将数据从内存中写入磁盘中
fileout.flush();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
if(file!=null){
file.close();
}
if(fileout!=null){
fileout.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
3.通过字节缓冲流提高读写效率
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamBuffer_Demo3 {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
fis=new FileInputStream("d:/movies/QQ飞车.jpg");
bis=new BufferedInputStream(fis);
fos=new FileOutputStream("d:/movies/b.jpg");
bos=new BufferedOutputStream(fos);
//在字节缓冲流中,其byte数组默认长度为2^13=8192
int temp=0;
while((temp=bis.read())!=-1){
bos.write(temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
//关闭流的顺序:后开的先关闭
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if(fos!=null){
fos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
4.定义文件拷贝工具类
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:/movies/QQ飞车.jpg", "d:/movies/bb.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));
int temp=0;
while((temp=bis.read())!=-1){
bos.write(temp);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
try {
if(bis!=null){
bis.close();
}
if(fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if(fos!=null){
fos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
五、常用流对象文件字符流
1.文件字符流
/**
*测试文件字符输入流
*/
import java.io.FileReader;
public class FileReader_Demo1 {
public static void main(String[] args) {
FileReader frd=null;
try {
//创建文件字符流对象
frd=new FileReader("d:/movies/app.txt");
int temp=0;
while((temp=frd.read())!=-1){
//一次只能读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即 unicode值)
System.out.println((char)temp);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(frd!=null){
frd.close();
}
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
}
}
}
}
/**
* 测试文件字符输出流
*/
import java.io.FileWriter;
public class FileWriter_Demo1 {
public static void main(String[] args) {
FileWriter fw=null;
FileWriter fw2=null;
try {
//创建文件字符输出流对象
fw=new FileWriter("d:/movies/aaa.txt");//自动创建文件
//一个字符流输出对象中调用多次write方法,会将内容连在一起
fw.write("TheMutents,我是小白\r\n");//\r\n代表回车换行,不同操作系统回车换行符不一样
fw.write("你好,世界!\r\n");
fw.flush();
//不同字符输出流对象往一个文件里写出数据,默认会将原来的文件内容覆盖掉
//fw2=new FileWriter("d:/movies/aaa.txt");//此字符输出流对象往同一文件写出数据会覆盖原来文件的内容
fw2=new FileWriter("d:/movies/aaa.txt", true);//此字符输出流对象往同一文件写出数据会在原来文件的内容上追加新内容
fw2.write("天将降大任于斯人也\r\n必先苦其心志\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.使用字符流实现文本文件的拷贝
import java.io.FileReader;
import java.io.FileWriter;
/**
* 使用字符流实现文本文件的拷贝
* */
public class FileTools_2 {
public static void main(String[] args) {
FileReader frd=null;
FileWriter fw=null;
try {
frd=new FileReader("d:/movies/aaa.txt");
fw=new FileWriter("d:/movies/bbb.txt");
//使用字符数组作为缓冲区,且只能给定数组长度,没有available()方法返回预估文件长度
char[] buff=new char[1024];
int temp=0;
while((temp=frd.read(buff))!=-1){
fw.write(buff, 0, temp);;
}
fw.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(frd!=null){
frd.close();
}
if(fw!=null){
fw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
3.字符缓冲流
BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率。
- 字符输入缓冲流
BufferedReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取。
/**
* 测试字符输入缓冲流
*/
import java.io.BufferedReader;
import java.io.FileReader;
public class ReaderBuffered_Demo1 {
public static void main(String[] args) {
FileReader fr=null;
BufferedReader br=null;
try {
fr=new FileReader("d:/movies/aaa.txt");
br=new BufferedReader(fr);
String temp=null;
//一次读一行,效率提高
while((temp=br.readLine())!=null){
System.out.println(temp);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(fr!=null){
fr.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
- 字符输出缓冲流
BufferedWriter是针对字符输出流的缓冲流对象,在字符输出缓冲流中可以使用newLine()方法实现换行处理。
/**
* 测试字符输出缓冲流
*/
import java.io.BufferedWriter;
import java.io.FileWriter;
public class WriterBuffered_Demo1 {
public static void main(String[] args) {
FileWriter fw=null;
BufferedWriter bw=null;
try {
fw=new FileWriter("d:/movies/ccc.txt");
bw= new BufferedWriter(fw);
bw.write("你好,世界!");
bw.write("你好,小白");
bw.newLine();//换行处理
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();
}
}
}
}
4.通过字符缓冲流实现文本的拷贝
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:/movies/aaa.txt","d:/movies/ddd.txt");
}
/**
* 基于字符缓冲流实现文件拷贝
*/
public static void copyFile(String src,String des){
FileReader fr=null;
BufferedReader br=null;
FileWriter fw=null;
BufferedWriter bw=null;
try {
fr=new FileReader(src);
br=new BufferedReader(fr);
fw=new FileWriter(des);
bw=new BufferedWriter(fw);
String temp=null;
while((temp=br.readLine())!=null){
bw.write(temp);
bw.newLine();
}
bw.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(fr!=null){
fr.close();
}
if(bw!=null){
bw.close();
}
if(fw!=null){
fw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
4.通过字符缓冲流实现为文件的内容添加行号
/**
* 为文件添加行号
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class LineNumDemo {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new FileReader("d:/movies/aaa.txt"));
bw=new BufferedWriter(new FileWriter("d:/movies/eee.txt"));
String temp=null;
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(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
六、常用流对象文件转换流
1.通过转换流实现键盘输入屏幕输出
/**
* 通过转换流实现键盘输入屏幕输出
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class ConvertStream_Demo {
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();
//System.out.println(input);//以字符的形式输出
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
2.通过字节流读取文本文件并添加行号
/**
* 通过字节流读取文本文件并添加行号
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class LineNum_Demo2 {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/movies/aaa.txt")));
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/movies/1.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(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
七、字符输出流
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
/**
* 使用字符输出流读取文本内容并给文本添加行号
*/
public class LineNum_Demo3 {
public static void main(String[] args) {
BufferedReader br=null;
PrintWriter pw=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/movies/aaa.txt")));
pw=new PrintWriter("d:/movies/2.txt");
int i=1;
String temp="";
while((temp=br.readLine())!=null){
pw.println(i+"."+temp);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(pw!=null){
pw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
八、字节数组流
1.字节数组输入流
/**
* 测试字节数组输入流
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class ByteArrayInputStream_Demo {
public static void main(String[] args) {
byte[] arr="TheMutents".getBytes();
StringBuilder sb=new StringBuilder();
//该构造方法参数为一个字节数组,代表数据源
ByteArrayInputStream bais=new ByteArrayInputStream(arr);
try {
int temp=0;
while((temp=bais.read())!=-1){
sb.append((char)temp);
}
System.out.println(sb);
} finally {
try {
bais.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.字节数组输出流
/**
* 测试字节数组输出流
*/
import java.io.ByteArrayOutputStream;
public class ByteArrayOutputStream_Demo {
public static void main(String[] args) {
ByteArrayOutputStream bos=null;
StringBuilder sb=new StringBuilder();
try {
bos=new ByteArrayOutputStream();
//将字节写入一个字节数组中
bos.write('l');
bos.write('h');
bos.write('k');
//获取字节数组
byte[] arr=bos.toByteArray();
//遍历字节数组
for(int i =0;i<arr.length;i++){
System.out.println(arr[i]);
sb.append((char)arr[i]);
}
System.out.println(sb);
} finally {
try {
if(bos!=null){
bos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
九、数据流
数据流将“基本数据类型与字符串类型"作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。
DatalnputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据(如:int、double、String 等)的方法。
1.数据输出流
/**
* 测试数据输出流
*/
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutputStream_Demo {
public static void main(String[] args) {
DataOutputStream dos=null;
try {
dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/movies/data1.txt")));
dos.writeChar('A');
dos.writeChars("theMutents");
dos.writeDouble(Math.random());
dos.writeInt(1000);
dos.writeUTF("你好,世界!");
dos.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(dos!=null){
dos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
2.数据输入流
通过数据输入流可以读取基于数据输出流向文件中写出的数据,且可以把这些数据按照相应的类型读取到程序中。
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
/**
* 测试数据输入流
*/
public class DataInputStream_Demo {
public static void main(String[] args) {
DataInputStream dis=null;
try {
dis=new DataInputStream(new BufferedInputStream(new FileInputStream("d:/movies/data1.txt")));
//读取的顺序要与写入的顺序一致,否则无法正确读取数据
System.out.println("char: "+dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readInt());
System.out.println(dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(dis!=null){
dis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
十、对象流
1.Java对象的序列化和反序列化
2.序列化涉及的类和接口
3.对象流操作基本数据类型
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* 测试对象输出流
*/
public class ObjectOutputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("d:/movies/data2.txt")));
oos.writeInt(100);
oos.writeDouble(Math.random());
oos.writeChar('a');
oos.writeBoolean(true);
oos.writeObject(new Date());
oos.writeUTF("写入文件完毕");
oos.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(oos!=null){
oos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
/**
* 测试对象输入流
*/
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:/movies/data2.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("Date: "+ois.readObject());
System.out.println("String: "+ois.readUTF());
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(ois!=null){
ois.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
4.对象流操作对象
- 将对象序列化到文件
import java.io.Serializable;
//对象流操作的对象的类必须实现Serializable接口
public class IO_User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String age;
public IO_User() {
super();
// TODO Auto-generated constructor stub
}
public IO_User(int id, String name, String age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamObjectTypeDemo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
//序列化:将对象转为字节。所以输出流一定为字节输出流
oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("d:/movies/object.txt")));
IO_User U1=new IO_User(1, "LHK", "20");
IO_User U2=new IO_User(2, "TheMutents", "20");
oos.writeObject(U1);
oos.writeObject(U2);
oos.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(oos!=null){
oos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
- 将对象反序列化到内存中
/**
* 从外部件对象反序列化到内存
*/
import java.io.BufferedInputStream;
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 BufferedInputStream(new FileInputStream("d:/movies/object.txt")));
IO_User u1=(IO_User)ois.readObject();
IO_User u2=(IO_User)ois.readObject();
System.out.println(u1.getId()+"\t"+u1.getName()+"\t"+u1.getAge());
System.out.println(u2.getId()+"\t"+u2.getName()+"\t"+u2.getAge());
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(ois!=null){
ois.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
十一、随机访问流
三个核心方法:
import java.io.RandomAccessFile;
/**
* 测试随机访问流
*/
public class RandomAccessFileDemo {
public static void main(String[] args) {
RandomAccessFile raf=null;
try {
raf=new RandomAccessFile("d:/movies/demo1/demo1.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);//指向文件内容的指针向后面移动4个字节
System.out.println(raf.readInt());
//隔一个int类型读一个数据
for(int i=0;i<arr.length;i+=2){
raf.seek(i*4);
System.out.print(raf.readInt()+"\t");
}
System.out.println();
//将40替换成45
raf.seek(12);
raf.writeInt(45);
for(int i=0;i<arr.length;i++){
raf.seek(i*4);
System.out.print(raf.readInt()+"\t");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(raf!=null){
raf.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
十二、File类在IO中的作用
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class File_In_IO_Demo {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new FileReader(new File("d:/movies/aaa.txt")));
bw=new BufferedWriter(new FileWriter(new File("d:/movies/demo1/demo2.txt")));
String Temp=null;
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(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
十三、Apache IO包
1.Apache基金会介绍
2.FileUtils的使用
常用方法:
- cleanDirectory:清空目录,但不删除目录。
- contentEquals:比较两个文件的内容是否相同。
- copyDirectory:将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的文件。
- copyFile:将一个文件拷贝到一个新的地址。
- copyFileToDirectory:将一个文件拷贝到某个目录下。
- copyInputStreamToFile:将一个输入流中的内容拷贝到某个文件。
- deleteDirectory:删除目录。
- deleteQuietly:删除文件。
- listFiles:列出指定目录下的所有文件。
- openInputSteam:打开指定文件的输入流。
- readFileToString:将文件内容作为字符串返回。
- readLines:将文件内容按行返回到一个字符串数组中。
- size:返回文件或目录的大小。
- write:将字符串内容直接写到文件中。
- writeByteArrayToFile:将字节数组内容写到文件中。
- writeLines:将容器中的元素的toString方法返回的内容依次写入文件中。
- writeStringToFile:将字符串内容写到文件中。
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
public class FileUtilsDemo {
public static void main(String[] args) throws IOException {
String content=FileUtils.readFileToString(new File("d:/movies/aaa.txt"), "UTF-8");
System.out.println(content);
}
}
/**
* FileUtils类实现文件拷贝
*/
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
public class FileUtilsDemo2 {
public static void main(String[] args) throws IOException {
FileUtils.copyDirectory(new File("d:/movies/demo1"),new File("d:/movies/deom2") , new FileFilter() {
//在文件拷贝时的过滤条件
@Override
public boolean accept(File pathname) {
if(pathname.getName().endsWith("txt")){
return true;
}
return false;
}
});
}
}
3.IOUtils的使用
常用方法:
- buffer方法:将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。
- closeQueitly方法:关闭流。
- contentEquals方法:比较两个流中的内容是否一致。
- copy方法:将输入流中的内容拷贝到输出流中,并可以指定字符编码。
- copyLarge方法:将输入流中的内容拷贝到输出流中,适合大于2G内容的拷贝。
- linelterator方法:返回可以迭代每一行内容的迭代器。
- read方法:将输入流中的部分内容读入到字节数组中。
- readFully方法:将输入流中的所有内容读入到字节数组中。
- readLine方法:读入输入流内容中的一行。
- toBufferedInputStream,toBufferedReader:将输入转为带缓存的输入流。
- toByteArray,toCharArray:将输入流的内容转为字节数组、字符数组。
- toString:将输入流或数组中的内容转化为字符串。
- write方法:向流里面写入内容。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
public class IOUtilsDemo {
public static void main(String[] args) throws FileNotFoundException, IOException {
String content=IOUtils.toString(new FileInputStream("d:/movies/aaa.txt"), "UTF-8");
System.out.println(content);
}
}