IO流:(Input Output)流
字符流的由来:其实就是字节流读取文字字节数据后,不直接操作而是先查指定的码表,获取对应的文字进行操作
简单说:字符流 = 字节流 + 编码表
字节流的两个顶层父类:InputStream、OutputStream
字符流的两个顶层父类:Reader、Writer
记住:如果要操作文字数据,建议优先考虑字符流
字符流的各类总结:
往一个文件中写入数据,那么在创建对象时,就必须明确该文件(用于存数数据的目的地)
如果文件不存在,会自动创建;如果文件存在,则会覆盖。
示例:
FileWriter fw = new FileWriter("demo.text");
调用Writer对象中的Writer(String)方法写入数据,其实是将数据写入到了临时存储缓冲区中
示例:
fw.writer("abc");
进行刷新,就能将数据直接写入到目的地中
示例:
fw.flush();
close() ==》 关闭资源,关闭此流(但需要先进行刷新),如果关闭后再写入writer()或者flush()将会导致Exception异常
close()和flush()的区别:
flush():将缓冲区的数据刷到目的地中后,流可以使用。
close():将缓冲区的数据刷到目的地中后,流就关闭了,该方法主要用于结束调用的底层资源。这个动作一定做。
在数据文件使用中使数据换行:System.getPropery(“line.separator”);
示例:
fw.writer("abc"+System.getPropery("line.separator")+"def");
如果构造函数中加入true,则可以实现对文件进行续写,如果没有加true,原来写入的数据将会被覆盖。
示例:
FileWriter fw = new FileWriter("Demo.text",true);
注意:在流对象的处理中,在try的外面创建引用变量,在try的里面进行引用变量的对象的初始化。
在创建变量、对象等对系统资源进行使用,在使用完成后必须关闭资源,而又因可能在使用过程中发生异常无法读取到关闭资源的语句close();因此需要放在finally{}中,又因为在关闭过程中可能发生异常,所以close()语句也需要单独try.
示例:
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("demo.txt",true);
fw.write("abcde");
}
catch (IOException e ){
System.out.println(e.toString()+"....");
}
finally{
if(fw!=null)
try{
fw.close();
}
catch (IOException e){
System.out.println("close:"+e.toString());
}
}
}
FileReader:读取文本文件
在创建读取流对象时,必须明确被读取的文件,一定要确定该文件是存在的
read()方法为FileReader()接口中的读取方法,读取的返回值为ASCII码,当读取完成后返回-1,且每次只读取一个。范围:0 - 65535
示例:
public class CopyTextTestText {
/**需求 从一个文本文档文件中复制其字符内容到另外一个文本文档中
* @param args
*/
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try{
/*读取指定的文本文档文件*/
fr = new FileReader("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoDemo.txt");
/*创建一个将获取到的文本文档字符写入指定的文本文档文件对象*/
fw = new FileWriter("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoText.txt");
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
/*通过while循环嵌套writ()方法书写到指定的文本文档文件*/
int ch =0;
try {
while((ch = fr.read()) != -1){
fw.write(ch);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*关闭两个被创建的流对象*/
finally{
try{
if(fr != null){
fr.close();
}
if(fr != null){
fw.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
read(char [] c) :将数据读入到数组中
示例:
public class CopyTextTest {
/**需求 使用read(char[])方法从一个文本文档文件中复制其字符内容到另外一个文本文档中
* @param args
*/
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw =null;
try {
/*创建一个读取流对象*/
fr = new FileReader("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoDemo.txt");
/*创建一个写入流d对象*/
fw = new FileWriter("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoText.txt");;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*定义一个char[]数组*/
char[] ch = new char[1024];
/*定义一个整形变量记录每次数组读入的字符数量便于后面write()方法写入*/
int leng = 0;
/*通过while()方法读取和写入*/
try {
while((leng = fr.read(ch)) != -1){
fw.write(ch,0,leng);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*关闭输入流和输出流*/
try {
if(fr != null)
fr.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if(fw != null)
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
字符的缓冲区
缓冲区的出现提高了对数据的读写效率
对应类:BufferWriter、BufferReader
缓冲区要结合流才可以使用(在构造函数中声明被缓冲数据的对象)
在流的基础上,对流的功能进行了增强
示例:
public class BufferedWrirerDemo {
/**熟悉缓冲区的使用
* 使用写入缓冲区
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*创建一个输入流*/
FileWriter fw = new FileWriter("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoDemo.txt");
/*为提高写入的效率创建缓冲区,并和要缓冲的对象相关联*/
BufferedWriter bw = new BufferedWriter(fw);
/*使用for循环和缓冲区的写入方法,将字符写入缓冲区*/
for (int i = 0; i < 4; i++) {
bw.write("abcdef"+i);
/*newLine()方法只仅仅局限于BufferWriter类中
* 而System.getProperty("line.separator"通用于所有的换行操作) */
bw.newLine();
/*使用缓冲区的刷新方法刷新数据*/
bw.flush();/*只有写入才需要刷新数据*/
}
/*使用缓冲区的方法关闭输入流*/
bw.close();
}
}
示例:
public class BufferedReaderDemo {
/**使用缓冲区读取字符
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*创建字符读取流*/
FileReader fw = new FileReader("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoDemo.txt");
/*创建读取流缓冲区对象*/
BufferedReader br = new BufferedReader(fw);
/*定义一个char[]数组*/
char[] buf = new char[1024];
/*定义一个整形变量记录每次数组读入的字符数量便于后面write()方法写入*/
int ch = 0;
/*使用while()循环嵌套嵌套缓冲区的read()方法读取字符数据*/
while((ch = br.read(buf)) != -1 ){
System.out.println(new String(buf,0,ch));
}
/*使用缓冲区的close()方法关闭读取流*/
br.close();
}
}
readLine和read的不同点:
readLine():读取一行字符;
read():读取一个字符;
readLine():读取换行符不会自动换行;
read():读取换行符会自动换行.
readLine()方法示例:
public class BUufferedReaderDemo2 {
/**使用BufferedReader()中的readLine()方法读取数据
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*创建一个读取流*/
FileReader fr = new FileReader("D:\\Andorid\\Java\\day20e\\src\\p1\\IO\\Writer\\FileWriter\\DemoDemo.txt");
/*创建读取流的缓冲区对象*/
BufferedReader bf = new BufferedReader(fr);
/*创建一个String类型的变量 通过此变量在循环中确定是否字符读取完*/
String line =null;
/*通过缓冲区对象中的readLine()方法和while嵌套读取文本中的字符*/
while((line = bf.readLine()) != null){
System.out.println(line);
}
/*关闭资源*/
bf.close();
}
}
装饰设计模式
对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
装饰和继承都能实现一样的特点:进行功能的拓展,增强
装饰设计模式相比继承的优势:
继承:使用一个类中的方法就继承其类,这样一来代码体就逐渐变得臃肿(每使用一个类中的方法就继承其类)
装饰设计模式:继承一组类的父类,通过多态的方式对其子类进行操作(装饰类和被装饰类都必须所属于同一个父类或者接口)
BufferReader的子类:LineNumberReader
LineNumberReader常用方法:
setLineNumber(int x):设置从第几行开始读取,缓冲数据
getLineNumber():获取每一行行标,从1开始。
字节流的各类总结:
FileInPutStream中available()方法:用于确定需要读取文本的字节大小
示例:
FileInPutStream fis = new FileInPutStream(“Demo.text”);
byte [] buf = new byte[fis.available]; //定义了一个和需要读取文本一样大小的数组,但是一定要小心使用,如果关联了一个内存大小为2G的电影,那么运行内存就完全不够加载,所以建议使用1024k的整数倍。
键盘录入示例:
InPutStream is = System.in;
int ch = is.read();
System.out.println(ch);
注意:如果定义了多次,键入一次,那么回车键(‘\r’,‘\n’)也会被录入其中。
默认的系统方法中其只有一个,例如:System.in如果通过close()方法将其关闭,则继后创建的System.in对象将无法使用。
字节、字符流的转换:
输入:
字节流转换成字符流===》通过Reader类中的子类
InputStreamReader(InputStream in )==》这是一个类,使用需要创建对象;in:需要转换的字节流对象;
注意:将字节流转换成字符流以后,则其就为字符,那么就可以使用字符流的缓冲区对其进行操作。
输出:
字符流转换为字节流==》通过Writer类中的子类
OutputStreamWriter(OutputStream out)
总结:1.字节流转换成字符流是在输入时
2.字符流转换成字节流是在输出时
示例:
InputStream in = System.in;//录入键盘输入数据(为字节流)
InputStreamReader isr = new InputStreamReader(in);//将字节流转换成字符流
BufferReader bufr = new BufferReader(isr);//创建字符流缓冲区,提高效率
String line = bufr.readLine();//读取缓冲区中的一行字符串数据,赋值给String变量line;
OutputStream out = System.out;//输出键盘上录入的数据(为字节流)
OutputStreamWriter osw = new OutputStreamWriter(out);//将原来为字符流的变量osw转换为字节流
BufferWriter bufw = new BufferWriter(osw);//创建字符流缓冲区,提高效率
bufw.write(line.toUpperCase());//通过字符串缓冲区write()方法向缓冲区中写入内容。
总结:
InputStreamReader和OutputStreamWriter创建的对象都为字符串String类型。其构造函数中传入的都是字节流Reader从上到下读取代码,Writer相反。
流的操作规律:
1,明确源和目的。
数据源:就是需要读取,可以使用两个体系:InputStream、Reader;
数据汇:就是需要写入,可以使用两个体系:OutputStream、Writer;
2,操作的数据是否是纯文本数据?
如果是:数据源:Reader
数据汇:Writer
如果不是:数据源:InputStream
数据汇:OutputStream
3,虽然确定了一个体系,但是该体系中有太多的对象,到底用哪个呢?
明确操作的数据设备。
数据源对应的设备:硬盘(File),内存(数组),键盘(System.in)
数据汇对应的设备:硬盘(File),内存(数组),控制台(System.out)。
4,需要在基本操作上附加其他功能吗?比如缓冲。
如果需要就进行装饰。
练习示例:
public class MP3CopyDemo2 {
/**拷贝一个MP3文件到另一个文件中
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*创建一个文件*/
File f1 = new File("E:\\周子琰 - 平凡之路.mp3");
/*创建一个读取流*/
FileInputStream fis = new FileInputStream(f1);
/*chuangji8an一个缓冲区,将读取到的内容存入到缓冲区中*/
BufferedInputStream bis = new BufferedInputStream(fis);
/*创建一个输出流,并指定其目的地文件*/
FileOutputStream fos = new FileOutputStream("E:\\平凡之路.mp3");
/*创建一个输出流缓冲区*/
BufferedOutputStream bos = new BufferedOutputStream(fos);
/*创建一个数组,定义每次在输出流中写入的数据量*/
byte[] buf = new byte[1024*1024];
int len = 0;
/*定义个while循环语句将数据通过写入流的循环写入到指定的目的地文件中*/
while((len = bis.read(buf))!= -1){
bos.write(buf,0,len);
}
/*关闭流*/
fis.close();
fos.close();
}
}
使用指定编码表的练习:
public class p7Text {
/**
* 将一个中文字符串按照指定的编码表写入到一个文本文件中
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*创建一个读取流读取一个文本文档*/
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Andorid\\Java\\dya22e\\src\\p4\\IO\\shiyan.txt")));
/*创建一个写入流,将文本文档按照指定的编码表写入到另外一个文件中*/
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\Andorid\\Java\\dya22e\\src\\p4\\IO\\jieguo.txt"),"UTF-8"));
String str = null;
while((str = br.readLine())!=null){
bw.write(str);
bw.flush();
}
}
}
File类
File类:将文件系统中的文件和文件夹封装成了对象。提供了更多的属性和行为可以对这些文件和文件夹进行操作。这些是流对象办不到的,因为流只操作数据。
File对象创建的三种方式:
1.File f = new File(File parent,String child)
示例:
File f = File("c\\");
File f1 = new File(f,"a.txt");
2.File f2 = new File(String pathName)
示例:
File f2 = new File("c\\a.txt");
- File f3 = new File(String parent,String name);
示例:
File f3 = new File("C\\","a.txt");
获取文件路径的两种方式:
1.String s = file.getAbsoublePath();//获取到的是全局路径
2.String s = file.getPath();//获取到的是相对路径
File类常用方法:
length()//获取文件剩余空间大小
craeteNewFile()//如果文件不存在就创建,如果文件存在则不创建
createTempFile(String prefix ==》文件前缀名,String suffix ==》 文件后缀名 )//在默认文件目录中创建一个空文件
craetTempFile(String prefix ==》文件前缀名,String suffix ==》 文件后缀名,File directory ==》 指定文件目录)
mkdir()//创建一个目录文件
mkdirs()//创建多层文件目录
delect()//删除,从里往外删,一层一层删
exists()//判断文件是否存在
isFile//判断是否为文件
isDirectory()//判断此文件是否含有文件
isHidden()//判断此文件是否含有隐藏文件
renameTo()//重置文件属性(前缀名,后缀名,路径)
示例:
File f1 = new File(“c:\0.mp3”);
File f2 = new File(“c:\9.mp3”);
boolean b = f1.renameTo(f2);
System.out.println(b);
结果为:
true
listRoots()//列出可用的文件系统根
示例:
File[] files = File.lsitRoots();
for(File file:files){
System.out.println(file);
}
getFreeSpace()//获取磁盘空间的可用空间大小
getTotalSpace()获取磁盘的总空间大小
getUsableSpace()//可用于此虚拟机的字节数
list过滤器的使用:
示例:
public class ListFilenameFilterDemo {
/**
* @param args
*/
public static void main(String[] args) {
File file = new File("c:\\");
String[] names = file.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
return name.endsWith("高速下载");
}
});
for(String name : names){
System.out.println(name);
}
}
}
注意:list的过滤器过滤出来的仅仅是文件的文件名
listFils的过滤器使用:
示例:
public class ListFileFilterDemo {
/**
* 操作使用File类中的listFiles()方法,获取当前目录下的文件对象
* @param args
*/
public static void main(String[] args) {
File file = new File("c:\\");
File[] fileAll = file.listFiles(/*当操作过滤隐藏文件时,所需操作的额是文件所以必须定义为:FileFilter*/new FileFilter(){
/*当操作修改文件名时,可在创建实现FilenameFilter接口的类中添加一个变量,将这个变量作为类的
* 构造函数参数,然后再作为accpt()方法的返回值;
* 这样一来在过滤的时候就不用在类中来回切换*/
@Override
public boolean accept(File dir) {
//返回当前目录下不是隐藏文件的文件
return !dir.isHidden();
}
});
for(File files : fileAll){
System.out.println(files);
}
}
}
注意:listFiles获取到的是当前目录下的文件(其操作过程的对象是文件,不是像list一样,操作的是文件的文件名)
递归
递归:函数自身调用自身或者间接的调用到了自身
一个函数功能被重复使用,并每次使用时,参与运算的结果和上一次调用有关,这时可以用递归解决问题
注意:递归一定要明确条件,否则容易栈溢出
IO流File类的删除操作
注意:
1.如果为空文件可以用delect()
2.如果不为空,则必须从里往外删(代码呈现方式与深度遍历目录相似)
IO流Properties集合
Properties集合特点:
1.该集合中的键和值都是字符串类型
2.集合中的数据可以保存在流中,或者从流中获取
3.通常该集合用于操作以键值对存在的配置文件
其取出元素主要用到的方法:
Set stringPropertyNames()//返回的是列表中的键集
setProperty(String key,String value)//修改元素的值
生成配置文件方法:
store(Write write,Stringcomments)、
store(OutputStream out,String comments)
示例:
public class PropertiesText {
/**
* 将Properties集合通过IO流存储到硬盘中
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//创Properties集合对象
Properties prop = new Properties();
//明确其输出在硬盘上的目的地
FileOutputStream fos = new FileOutputStream("D:\\Andorid\\Java\\day23e\\src\\p3\\Properties\\Text\\iofo.txt");
//将数据存储到集合中
prop.setProperty("wangwu","25");
prop.setProperty("qiqi","34");
prop.setProperty("wangcai","65");
prop.setProperty("xiaoqing","36");
prop.setProperty("xiaoqiang","78");
//将集合通过stor()方法将集合存储到硬盘中
prop.store(fos, "name+age");
//关闭流
fos.close();
}
}
从输入流中读取属性列表方法:
load(InputSream is)、load(Reader reader)
示例:
public class PerprotiesloadText {
/**
* 模拟load()方法:
* 通过IO流的读取流读取配置文件中的数据(元素的 :键和值)
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// 创建Properties对象
Properties prop = new Properties();
// 流读取配置文件数据
BufferedReader br = new BufferedReader(
new FileReader(
"D:\\Andorid\\Java\\day23e\\src\\p3\\Properties\\Text\\iofo.txt"));
// 输出配置文件信息(元素的:键和值)到控制台上
String str = null;
while ((str = br.readLine()) != null) {
if(str.startsWith("#")){
continue;
}
else{
String[] str1 = str.split("=");
// System.out.println(str1[0]+":"+str1[1]);
prop.setProperty(str1[0],str1[1]);
}
}
prop.list(System.out);
}
}
IO流PrintStream
PrintStream:一般用于多字节
PrintStream特点:
1.提供了打印方法可以对多种数据类型值进行打印,并保持了数据的原有形式
2.它不抛IOException异常
构造函数接收三种类型的值
1.字符串路径
2.File对象
3.字节输出流
PrintStream(File file) :创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn) :创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding) :创建新的打印流。
PrintStream(String fileName) :创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(String fileName, String csn)
示例:
PrintStream out = new PrintStream("print.txt");
out.print(97);//将97变成字符保持原样将数据打印到目的地
out.wrint(610);//只写最低八位,前24为舍弃
out.close();
PrintWriter:具备了PrintStream的特点同时,还有自身特点:
构造函数接收四种类型的值
1.字符串路径
2.File对象
3.字节输出流
4.字符输出流
(序列流)SequenceInputStream
SequenceInputStream作用:将多个读取流合并成一个读取流。实现数据合并。
对文件的切割:
public static void main(String[] args) throws IOException {
/**
*@ param
*对文件的分割
*/
//创建读取流
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试\\test\\ABC.mp3");
//创建数组
byte[] buf = new byte[1024*1024];
int len = 0;
int cont = 1;
FileOutputStream fos = null;
//通过while循环输出被分割的文件
while((len = fis.read(buf)) != -1){
//创建一个输出流
fos = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\测试\\test",cont+".part"));
cont++;
fos.write(buf,0,len);
//关闭流
}
fos.close();
fis.close();
}
}
对文件的合并:
public static void main(String[] args) throws IOException {
//创建一个集合
ArrayList<FileInputStream> list= new ArrayList<FileInputStream>();
//创建一个读取流
FileInputStream fis = null;
//for循环将读取到的切割文件装到集合中
for (int i = 1; i < 5; i++) {
fis = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\测试\\test",i+".part"));
list.add(fis);
}
//创建一个枚举,排序集合
Enumeration en = Collections.enumeration(list);
//创建一个SequenceInputStream流
SequenceInputStream sis = new SequenceInputStream(en);
//创建一个数组
byte[] buf = new byte[1024];
int len= 0;
//创建一个输出流
FileOutputStream fos = null;
//while循环暑促
while((len = sis.read(buf)) != -1){
fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\测试\\test\\bcde.mp3");
fos.write(buf,0,len);
}
//关闭流
fis.close();
fos.close();
}
带有配置信息的文件分割:
public static void main(String[] args) throws IOException {
//创建一个读取流
FileInputStream fis = new FileInputStream
("C:\\Users\\Administrator\\Desktop\\测试\\test\\ABC.mp3");
//创建一个数组
byte[] buf = new byte[1024*1024];
//创建一个输出流
FileOutputStream fos = null;
int len = 0;
int cont = 1;
File file = new File("C:\\Users\\Administrator\\Desktop\\测试\\test");
//创建一个while循环
while((len = fis.read(buf)) != -1){
fos = new FileOutputStream
(new File(file,cont+".part"));
cont++;
}
//创建Properties
Properties prop = new Properties();
//设置Properties中的属性
String filename = file.getName();
prop.setProperty("filename",filename);
prop.setProperty("partcount",cont+"");
File config = new File(file,cont+".properties");
fos = new FileOutputStream(config);
//使用Properties中的store方法生成配置文件信息
prop.store(fos, null);
//关闭流
fos.close();
fis.close();
}
带有配置信息的文件合并:
public static void main(String[] args) throws IOException {
//创建一个集合
ArrayList<FileInputStream> list =new ArrayList<FileInputStream>();
//创建一个读取流
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试\\0.MP3\\5.properties");
//创建一个Properties
Properties prop = new Properties();
//获取配置信息
prop.load(fis);
int cont = Integer.parseInt(prop.getProperty("partcount"));
//创建一个for循环将读取到的数据存入集合
for (int i = 1; i < cont; i++) {
fis = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\测试\\0.MP3",i+".part"));
list.add(fis);
}
//创建一个枚举
Enumeration en = Collections.enumeration(list);
//创建一个SequenceInputStream
SequenceInputStream sis = new SequenceInputStream(en);
//创建一个输出流
FileOutputStream fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\测试\\0.MP3"+prop.getProperty("filename"));
byte[] buf = new byte[1024];
int len = 0;
//创建一个while循环写入数据
while((len = sis.read(buf)) != -1){
fos.write(buf,0,len);
}
//关闭流
fis.close();
fos.close();
}
(对象的序列化)ObjectInputStream
ObjectInputStream:将一个具体的对象进行持久化,写入到硬盘上
注意:
1.被序列化的对象必须实现Serializable接口
2.静态数据不能被序列化,因为静态数据不在堆内存中,是存储在静态方法区中
3.如果变量不想被写入硬盘,且不为静态的公共数据则可对变量使用transient做修饰符即可
示例:private transient String name;
4.Serializable:用于给被序列化的类加入ID号和用于判断类和对象是否是同一版本
示例:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",25)); //写入一个对象。
oos.close();
对象的反序列化:
public static void readObj()throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Object obj = ois.readObject();//读取一个对象。
System.out.println(obj.toString())
RandomAccessFile
RandomAccessFile特点:
1.该对象既能读,又能写
2.该对象内部维护了一个byte数组,且为大型的,并通过指针可以操作数组中的元素
3.可以通过getFilePointer方法读取指针的位置,并通过seek方法设置指针的位置
4.其实就是将字节流的读取和写入进行了封装
5.该对象的源或者目的都只能是文件
管道流:
PipedInputStream 和 PipedOutputStream
管道流的特点:
1.输入输出可以直接进行连接,通常结合现场
2.管道读取流逝读取管道输出流的额数据
对于管道读取流确定管道输出流有两种方式:
1.
创建好对象后,通过connect()确定
PipedInputStream pipin = new PipedInputStream();
PipedOutputStream pipout = new PipedOutputStream();
pipin.connect(pipout);
2.在构造函数中确定
PipedInputStream( PipedOutputStream src)