IO
字节流
FileInputStream
FileInputSteam
:用于读取诸如图像数据的原始字节流
FileInputStream常用方法:
FileInputStream(File file)
//创建文件输入流read()
//从该输入流读取一个字节的数据read(byte[] b)
//从该输入流读取最多b.length
个字节的数据为字节数组。read(byte[] b, int off, int len)
//从该输入流读取最多len
字节的数据为字节数组。
读文件
mport java.io.File;importjava.io.FileInputStream;importjava.io.IOException;publicclassFileInput{publicstaticvoidmain(String[] args)throwsIOException{//utf-8进行存储,一个英文字母占一个字节,一个中文占3个字节//如果文本文件,那么就不要使用字节流读取了,建议使用字符流//read()读取一个字节,返回int类型,都是正数//方式一:Input01();//方式二Input02();}publicstaticvoidInput01()throwsIOException{//利用字节流读取文件File file =newFile("E:\\test.txt");FileInputStream fi =newFileInputStream(file);int read = fi.read();while(read!=-1){System.out.print((char)read);
read=fi.read();}
fi.close();}publicstaticvoidInput02()throwsIOException{FileInputStream fi=newFileInputStream(newFile("E:\\test.txt"));byte[] b=newbyte[8];int len=fi.read(b);while(len!=-1){for(int i=0;i<len;i++){System.out.print((char) b[i]);}
len=fi.read(b);}
fi.close();}}
FileOutputStream
FileOutputStream
用于写入诸如图像数据的原始字节流。
FileOutputStream常用方法:
FileOutputStream(File file)
//创建文件输出流以写入由指定的File
对象表示的文件。FileOutputStream(File file,boolean append)
//创建文件输出流以覆盖(false)或者追加(true)的方式写入。write(int b)
//将指定的字节写入此文件。write(byte[] b)
//将b.lenth
个字节从指定数组写入此文件中。
写文件
importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.nio.charset.StandardCharsets;publicclassFileOutput{publicstaticvoidmain(String[] args)throwsIOException{FileOutputStream fo=newFileOutputStream(newFile("E:\\demo.txt"));String str="hello java!";//写入的内容byte[] b = str.getBytes(StandardCharsets.UTF_8);//按utf-8编码格式转成字节数组
fo.write(b);//写入操作
fo.close();//关闭流}}
文件拷贝
importjava.io.*;publicclassFileCopy{publicstaticvoidmain(String[] args)throwsIOException{File f1 =newFile("E:\\test.txt");File f2 =newFile("E:\\demo.txt");FileInputStream fi =newFileInputStream(f1);FileOutputStream fo =newFileOutputStream(f2);byte[] b =newbyte[8];int len = fi.read(b);while(len !=-1){
fo.write(b,0, len);
len = fi.read(b);}
fo.close();
fi.close();}}
字符流
FileReader
FileReader
:是用于读取字符流。
FileReader常用方法:
new FileReader(File file);
//构造方法read();
//每次读取单个字符,返回该字符,如果读到文件末尾返回-1read(char[] ch);
//读取多个到数组,返回读取到的字符数,如果到文件末尾返回-1
读文件
importjava.io.File;importjava.io.FileReader;importjava.io.IOException;publicclassFileRead{publicstaticvoidmain(String[] args)throwsIOException{//方式一Read01();//方式二Read02();}publicstaticvoidRead01()throwsIOException{String path ="E:\\Test\\test01.txt";File file =newFile(path);FileReader fileReader =newFileReader(file);int read = fileReader.read();while(read !=-1){System.out.print((char) read);
read = fileReader.read();}
fileReader.close();}publicstaticvoidRead02()throwsIOException{File file =newFile("E:\\Test\\test01.txt");FileReader fileReader =newFileReader(file);char[] ch =newchar[8];int len = fileReader.read(ch);//缓冲数组while(len !=-1){// for (int i=0;i<len;i++){// System.out.print(ch[i]);// }// len=fileReader.read(ch);//将数组转为stringString str =newString(ch,0, len);System.out.print(str);
len = fileReader.read(ch);}
fileReader.close();}}
FileWriter
FileWriter
:是用于写入字符流。
FileWriter常用方法:
new FileWriter(File file,boolean true);
//构造方法,如果目标文件不存在,就自动创建该文件,默认为false,对源文件进行覆盖操作,true,对源文件末尾进行追加。write();
//写入单个字符write(char[] ch);
//写入指定数组内容,也可写入数组的指定部分write(String str);
//写入指定字符串,也可写入字符串的指定部分
注意:FileWriter使用后,必须要关闭(close)或者刷新(flush),否者写入不到指定文件!
写文件
importjava.io.*;publicclassFileWrite{publicstaticvoidmain(String[] args)throwsIOException{//一个一个字符写入// new FileWriter(file,false)对源文件按进行覆盖操作// new FileWriter(file,true)对源文件进行追加,而不是覆盖Write01();//利用缓冲数组输出Write02();}publicstaticvoidWrite01()throwsIOException{//如果目标文件不存在的话,那么会自动创建此文件File file =newFile("E:\\test.txt");FileWriter fileWrite =newFileWriter(file,true);String str ="hello java!!!";for(int i =0; i < str.length(); i++){
fileWrite.write(str.charAt(i));}
fileWrite.close();}publicstaticvoidWrite02()throwsIOException{File file =newFile("E:\\test.txt");FileWriter fileWriter =newFileWriter(file,true);String str ="你好,java!";char[] chars = str.toCharArray();
fileWriter.write(chars);
fileWriter.close();}}
文件拷贝
importjava.io.*;//注意:不要用字符流去操作非文本文件/*
* 文本文件:.txt/.java/.c/.cpp-->建议使用字符操作
* 非文本文件:.jpj/.mp3/.mp4/.doc/.ppt-->建议使用字节流操作
* */publicclassFileCopy{publicstaticvoidmain(String[] args)throwsIOException{//有一个源文件和一个目标文件File f1 =newFile("E:\\test.txt");File f2 =newFile("E:\\demo.txt");//输入输出FileReader fileReader =newFileReader(f1);FileWriter fileWriter =newFileWriter(f2);//一个一个字符复制// int read=fileReader.read();// while (read!=-1){// fileWriter.write(read);// read=fileReader.read();// }//利用字符数组char[] ch=newchar[1024];int len=fileReader.read(ch);while(len!=-1){String str=newString(ch,0,len);
fileWriter.write(str);//fileWriter.write(ch,0,len);
len=fileReader.read(ch);}//关闭流
fileWriter.close();
fileReader.close();}}
缓冲(处理)流
一般情况下,我们使用字节字符流时,每次都是从源文件中读取/写入数据,这种操作效率比较低。
而利用缓冲(处理流),在程序(内存)里开辟一个缓冲区,然后在缓冲区里进行数据的读写,这样就不用每次都到源文件中操作。
缓冲流的使用
- 创建文件对象(new File())
- 创建输入输出流对象(new FileInputStream()/new FileReader())
- 创建缓冲流对象(new BufferedInputStream(fi)/new BufferedReader(fr))
- 利用缓冲流操作读写(read()/write())
- 关闭流(bf.close())
如果处理流包裹着节点流的话,那么其实只要关闭高级流(处理流),那么里面的字节流也会随之被关闭。
缓冲字节流
当创建
BufferedInputStream
时,将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次有多个字节。
BufferedOutputStream
实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。
常用方法:
new BufferedInputStream(InputStream in)
//创建一个 BufferedInputStream并保存其参数,输入流 innew BufferedInputStream(InputStream in,int size)
//创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 inread()
//与InputStream中read()
用法相同read(byte[] b,int off,int len)
// 与InputStream中read(byte[] b,int off,int len)
相同BufferedOutputStream(OutputStream out)
//创建一个新的缓冲输出流,以将数据写入指定的底层输出流。BufferedOutputStream(OutputStream out, int size)
//创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流write(byte[] b, int off, int len)
//从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。write(int b)
//将指定的字节写入缓冲的输出流。
利用缓冲字节流对文件的拷贝
importjava.io.*;publicclassBufferedStream{publicstaticvoidmain(String[] args)throwsIOException{FileInputStream fi =newFileInputStream(newFile("E:\\test.txt"));FileOutputStream fo =newFileOutputStream(newFile("E:\\demo.txr"));BufferedInputStream bis=newBufferedInputStream(fi);BufferedOutputStream bos=newBufferedOutputStream(fo);byte[] b=newbyte[1024];int len=bis.read(b);while(len!=-1){
bos.write(b,0,len);
len=bis.read(b);}
bos.close();
bis.close();}}
缓冲字符流
在使用字符缓冲流读文件时,使用
readLine()
可以读一行文字,返回的是一个字符串,如果我们要对这读取到这一行进行写操作时,就要手动的在下面添加换行,
newLine()
,不然的话会把所有的内容都写在同一行
利用缓冲字符流对文件的拷贝
importjava.io.*;publicclassBufferedRW{publicstaticvoidmain(String[] args)throwsIOException{FileReader fr=newFileReader(newFile("E:\\test.txt"));FileWriter fw=newFileWriter(newFile("E:\\demo.txt"));BufferedReader bfr=newBufferedReader(fr);BufferedWriter bfw=newBufferedWriter(fw);String str=bfr.readLine();while(str!=null){
bfw.write(str);
bfw.newLine();
str=bfr.readLine();}
bfw.close();
bfr.close();}}
打印流
System.out
:标准的输出流,默认情况下输出到控制台,返回的是打印流(PrintStream)
importjava.io.PrintStream;publicclassTest{publicstaticvoidmain(String[] args){PrintStream out =System.out;
out.print("hello");//直接在控制台上写出,不换行
out.println("java");//直接在控制台上写出,并且换行操作System.out.println("hello world");}}
System.in
:标准输入流,默认情况下,从键盘输入
Scanner
:起扫描作用,扫描从键盘上输入的数据,还可以扫描其他流的数据
importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.util.Scanner;publicclass input {publicstaticvoidmain(String[] args)throwsIOException{InputStream in =System.in;//得到标准的输入流int a=in.read();System.out.println(a);//Scanner可以扫描其他流的数据Scanner sc=newScanner(System.in);int b=sc.nextInt();System.out.println(b);//Scanner扫描文件Scanner input=newScanner(newFileInputStream(newFile("E:\\test.txt")));while(input.hasNext()){System.out.println(input.next());}}}
转换流
转换流的作用
将字节流和字符流进行转换
转换流属于字节流还是字符流?
属于字符流
InputStreamReader:字节输入流–>字符输入流
OutputStreamWriter:字符输出流–>字节输出流
使用转换流对文件的复制
importjava.io.*;publicclassTest02{//这是一个main方法,是程序的入口:publicstaticvoidmain(String[] args)throwsIOException{//1.有一个源文件File f1 =newFile("d:\\Test.txt");//2.有一个目标文件:File f2 =newFile("d:\\Demo.txt");//3.输入方向:FileInputStream fis =newFileInputStream(f1);InputStreamReader isr =newInputStreamReader(fis,"utf-8");//4.输出方向:FileOutputStream fos =newFileOutputStream(f2);OutputStreamWriter osw =newOutputStreamWriter(fos,"gbk");//5.开始动作:char[] ch =newchar[20];int len = isr.read(ch);while(len!=-1){
osw.write(ch,0,len);
len = isr.read(ch);}//6.关闭流:
osw.close();
isr.close();}}
数据流
数据流:就是用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串写入内存变量中
DataOutputStream:将内存中的基本数据类型和字符串的变量写出文件中
利用DataOutputStream向外写出变量
publicclassTest01{//这是一个main方法,是程序的入口:publicstaticvoidmain(String[] args)throwsIOException{//DataOutputStream: 将内存中的基本数据类型和字符串的变量 写出 文件中File f =newFile("d:\\Demo2.txt");FileOutputStream fos =newFileOutputStream(f);DataOutputStream dos =newDataOutputStream(fos);//向外将变量写到文件中去:
dos.writeUTF("你好");
dos.writeBoolean(false);
dos.writeDouble(6.9);
dos.writeInt(82);//关闭流:
dos.close();}}
打开文件可以看到,内容我们看不懂,这是给程序看的
我们用程序读取
importjava.io.*;publicclassTest02{//这是一个main方法,是程序的入口:publicstaticvoidmain(String[] args)throwsIOException{//DataInputStream:将文件中存储的基本数据类型和字符串 写入 内存的变量中DataInputStream dis =newDataInputStream(newFileInputStream(newFile("d:\\Demo2.txt")));//将文件中内容读取到程序中来:System.out.println(dis.readUTF());System.out.println(dis.readBoolean());System.out.println(dis.readDouble());System.out.println(dis.readInt());//关闭流:
dis.close();}}
输出
要求:写出的类型跟读入的类型 必须 要匹配!
对象流
数据流:就是用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串写入内存变量中
DataOutputStream:将内存中的基本数据类型和字符串的变量写出文件中
序列化和反序列化
- 序列化就是在保存数据时,保存数据的值和数据类型
- 反序列化就是在恢复数据时,恢复数据的值和数据类型
需要让某个对象支持序列化和反序列化机制,则必须让其类是可序列化的,为了让某个类可序列化的,该类必须实现两个接口之一:
Serializable
:标记接口,接口内部,什么都没有,这种接口叫 标识接口。起到标识作用,标识什么呢?只要实现这个接口的类的对象才能序列化,否则不可以。Externalizable
:一般不使用
serialVersionUID:凡是实现Serializable接口(标识接口)的类都有一个表示序列化版本标识符的静态常量
- private static final long serialVersionUID
- serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序加化时是否兼容
- 如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
- 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
IDEA配置序列化版本号
alt+enter
序列化细节:
- 被序列化的类的内部的所有属性,必须是可序列化的 (基本数据类型都是可序列化的)
- static,transient修饰的属性 不可以被序列化。
publicclassPersonimplementsSerializable{privatestaticfinallong serialVersionUID =8027651838638826533L;privatetransientString name;privatestaticint age;publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}publicPerson(){}@OverridepublicStringtoString(){return"Person{"+"name='"+ name +'\''+", age="+ age +'}';}}
测试方法
publicclassTest01{publicstaticvoidmain(String[] args)throwsIOException{//序列化:将内存中对象 ---》 文件://有一个对象:Person p =newPerson("张三",19);//有对象流:ObjectOutputStream oos =newObjectOutputStream(newFileOutputStream(newFile("d:\\Demo4.txt")));//向外写:
oos.writeObject(p);//关闭流:
oos.close();}}
publicclassTest02{publicstaticvoidmain(String[] args)throwsIOException,ClassNotFoundException{ObjectInputStream ois =newObjectInputStream(newFileInputStream(newFile("d:\\Demo4.txt")));//读入内存:Person p =(Person)(ois.readObject());System.out.println(p);//关闭流:
ois.close();}}
版权归原作者 Tangable22 所有, 如有侵权,请联系我们删除。