**
**
RandomAccessFile类
:操作文件,按字节的方式,字节流,可读可写
RandomAccessFlie(File file,String mode);
创建从中读取和向其中写入随机访问流,文件通过file指定 (new File(“路径”)),模式通过mode指定
RandomAccessFile raf1=new RandomAccessFile(new File("d:/aa/aa.txt"), "r");
RandomAccessFile(String name,String mode);
创建从中读取和向其中写入随机访问流,文件通过name指定 (“路径”),模式通过mode指定
RandomAccessFile raf2=new RandomAccessFile(("d:/aa/aa/txt"), "rw");
mode的取值 "r" 只读模式; "rw" 读写模式
-写入操作
void write(int d);在当前指针位置写一个字节
raf1.write(65);
void write(byte[] b);在当前位置写入一组字节
raf1.write("hello world".getBytes());
void write(byte[] b,int offset,int len);将指定长度(len)的字节从指定的数组(b)的指定偏移量(offset)开始的内容,写入文件
raf1.write("hello world".getBytes(),1,6);
-读写操作
int read();从文件中读取一个字节,填充到整形的低8位,若返回-1,表示读到文件末尾
int d=raf1.read();
System.out.println(d);
int read(byte[] b);从指针位置开始读取并存储数组(b)长度的字符,返回值为读取的长度,有时会遇到返回长度小于数组长度,返回值为-1,表示读到文件末尾
byte[] buf= new byte[3];
int len=raf1.read(buf);
System.out.println(raf1.getFilePointer()+" "+new String (buf)+" "+len);
int read(byte[] b,int offset,int len);将最多len个数据存到数组(b)中,存储位置从偏移量(offset)开始
byte[] buf= new byte[5];
int len=raf1.read(buf,1,3);
System.out.println(raf1.getFilePointer()+" "+new String (buf)+" "+len);
for(byte b: buf){
System.out.println(b);
}
void getPointer();返回当前指针位置
raf1.write('a');
System.out.println(raf1.getFilePointer());//1
void seek(long position);设置文件开始到文件指针偏移量的位置,在下一位置进行读写操作
raf1.seek(4);//hello world
int d=raf1.read();
System.out.println(d);//32
int skipByte(int n);用此方法可以跳过一些少量字节,只能是正数,(其实是从当前指针位置开始算的)
raf1.skipBytes(4);//hello world
int d=raf1.read();
System.out.println((char)d);//o
字节流:
InputStream
是所有的字节流的父类,其定义了基础的读取方法
int read();从文件中读取一个字节,填充到整形的低8位,若返回-1,表示读到文件末尾
int d=-1;
while((d=is.read())!=-1){
System.out.println((char)d);
}
int read(byte[] b);从指针位置开始读取并存储数组(b)长度的字符,返回值为读取的长度,有时会遇到返回长度小于数组长度,返回值为-1,表示读到文件末尾
int read(byte[] b,int offset,int len);将最多len个数据存到数组(b)中,存储位置从偏移量(offset)开始
byte[] buf=new byte[3];
int len=-1;
while((len=is.read(buf))!=-1){
System.out.println("len"+len+" "+new String (buf).substring(0,len));
}
void close();关闭该流,释放相关联的资源
is.close();
FileInputStream:文件输入流
-可以操作文件内容
-操作的是字节流
-继承自InputStream抽象类
-低级流
-操作的是文件
InputStream is=new FileInputStream("d:/aa/aa.zip");
OutputStream
是所有的字节流的父类,其定义了基础的写出方法
void write(int d);写出整形数据的低8位
os.write(97);
void write(byte[] b);将给定字节数组的数据全部写出
os.write("hello world!".getBytes());
void write(byte[] b,int offset ,int len);将给定的字节数组从偏移量offset开始的len个字节写入输出流
byte[] buf= new byte[1024*1024];//缓冲
int len= -1;
while((len=is.read(buf))!=-1){
os.write(buf,0,len);
}
void flush()刷新此输出流并强制写出所有的缓冲的输出字节
os.flush();
void close();关闭该流,释放相关联的资源
os.close();
FileOutputStream:文件输出流
-可以操作文件内容
-操作的是字节流
-继承自OutputStream抽象类
-低级流
-操作的是文件
OutputStream os=new FileOutputStream("d:/aa/aa1.zip");
缓冲字节流:Buffered缓冲,高级流之一 , 关注传递的速度,性能
缓冲流的原理:
向硬件存储设备或操作数据,导致增大跟硬件的交互次数,会降低读写的速度,
做缓冲流的目的就是为了尽量减少跟硬件的交互次数
缓冲输出流的原理BufferedOutputStream:缓冲输出流内不会维护一个缓冲区
每当我们向该流写出数据时,都会先将数据存入缓冲区
当缓冲区已满的时候,缓冲流会将数据一次性写出到硬盘
/**
* 缓冲输出流
* 减少跟硬盘的交互次数
* @throws IOException
*/
@Test
public void testMethod1() throws IOException{
//低级流,文件的字节流
OutputStream os = new FileOutputStream("d://aa//bos.txt");
//对低级流,做二次封装,转换成高级流
BufferedOutputStream bos=new BufferedOutputStream(os);
//用高级流的对象打点调用api方法,读写效率会有提升
bos.write("hello world".getBytes());//此时没有写呢!!1
//清空缓冲,强制回写硬盘
bos.flush();
//关闭流的资源
bos.close();
os.close();
}
注意: void flush();清除缓冲区,将缓冲区的数据强制写出,以保证数据的完整
缓冲输入流原理:BufferedInputStream缓冲输入流内部会维护一个缓冲区
每当我们向该流读入数据,都会先将数据存入(写入到内存)缓冲区,BufferedInputStream 的read方法会从缓冲区读取数据,
当缓冲区全部读取完毕,如果再次read的时候,会再一次把缓冲区填满.然后read在逐一从缓冲区读取数据,以此往复.
/**
* 缓冲输入流
* 减少跟硬盘的交互次数
* @throws IOException
*/
@Test
public void testMethod2() throws IOException{
//低级的输入流
InputStream is = new FileInputStream("d:/aa/bos.txt");
//高级的缓冲输入流
BufferedInputStream bis = new BufferedInputStream(is);
int d =-1;
while((d=bis.read())!= -1){
System.out.println((char)d);
}
bis.close();
is.close();
}
案例:
/**
* 用缓冲流的方式进行文件复制
* 单字节
* 已经减少了与硬盘的交互次数
* @throws IOException
*/
@Test
public void testMethod3() throws IOException{
System.out.println("开始复制");
long begin = System.currentTimeMillis();
//构建输入低级流
InputStream is= new FileInputStream("d:/aa/tedu.zip");
//构建输入高级流
BufferedInputStream bis = new BufferedInputStream(is);
//构建输出低级流
OutputStream os= new FileOutputStream("d:/aa/tedu4.zip");
//构建输出高级流
BufferedOutputStream bos = new BufferedOutputStream(os);
//单字节复制
int d=-1;
while((d=bis.read())!= -1){
bos.write(d);
}
bos.close();
os.close();
bis.close();
is.close();
long end = System.currentTimeMillis();
System.out.println("开始复制"+(end-begin));
}
/**
* 用缓冲流的方式进行文件复制
* 多字节
* 1.减少了与硬盘的交互次数
* 2.人为自己做一个缓冲,减少循环数
*
* @throws IOException
*/
@Test
public void testMethod4() throws IOException{
System.out.println("开始复制");
long begin = System.currentTimeMillis();
//构建输入低级流
InputStream is= new FileInputStream("d:/aa/tedu.zip");
//构建输入高级流
BufferedInputStream bis = new BufferedInputStream(is);
//构建输出低级流
OutputStream os= new FileOutputStream("d:/aa/tedu5.zip");
//构建输出高级流
BufferedOutputStream bos = new BufferedOutputStream(os);
//多字节复制
byte[] buf = new byte[1024*1024];
int len=-1;
while((len=bis.read(buf))!= -1){
bos.write(len);
}
bos.close();
os.close();
bis.close();
is.close();
long end = System.currentTimeMillis();
System.out.println("开始复制"+(end-begin));
}
缓冲是靠牺牲内存来提升io的读写效率
对象流:高级流之一,关注的是功能,对象
把内存的对象数据,序列化到硬盘上,也可以把硬盘上的文件反序列化回内存的对象
序列化:把内存的对象序列化到硬盘,以字节的方式体现
/**
* 序列化对象到硬盘中
* @throws IOException
*/
@Test
public void testMethod() throws IOException{
Student stu1=new Student();
stu1.setName("zhangsan ");
stu1.setAge(33);
stu1.getNum();
//构建低级流
OutputStream os = new FileOutputStream("d:/aa/student.data");
//构建高级流 对象输出流
ObjectOutputStream oos= new ObjectOutputStream(os);
oos.writeObject(stu1);
oos.flush();
oos.close();
os.close();
}
反序列化:把硬盘上的字节序列,反序列化回内存中的对象
/**
* 反序列化操作
* @throws IOException
*/
@Test
public void testMethod2() {
try {
//构建低级输入流
InputStream is = new FileInputStream("d:/aa/student.data");
//构建对象高级输出流
ObjectInputStream ois = new ObjectInputStream(is);
Student stu = (Student)ois.readObject();
System.out.println(stu);
ois.close();
is.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
java.io.Serializable接口
:
此接口仅表示可序列化语义,某个李实现这个接口.’
就是说这个类表示了可以序列化这个语义,zhe
这个类的子类也同样具备序列化语义,这个类需要提供一个 serialVersionUID
用来表示奔雷的序列化版本号
如果想跨平台,就需要显示声明一个版本号,且平台两端的版本必须相同
序列化类中可以有很多的属性,但部分属性不想被序列化和反序列化
把类中的不需要序列化的属性前加上transient修饰符
transient:短暂的,瞬间的
注意:
要实现对象的序列化和反序列化,就必须对序列化的对象
所对应的类实现java.io.Serializable接口
且类中最好提供一个long类型 的序列化的版本号
比如:
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;//可以序列化
private int age;//可以序列化
private transient String num;//不可以序列化
//getter and setter略
}
数据流:
DataInputStream 数据输入流,适合对hava基本数据类型的输入
构造函数:
DataInputStream (InputStream);
api方法:
readInt();类似这样的方法readXXX();XXX代表具体的某种类型
/**
* DataInputStream 数据输出流
* @throws IOException
*/
@Test
public void testMethod2() throws IOException{
//构建低级流
InputStream is= new FileInputStream("d:/aa/dos.txt");
//封装低级流微数据的高级流
DataInputStream dis= new DataInputStream(is);
//需要知道位置是什么类型的数据,这两个位置不能替换
int value=dis.readInt();
String str= dis.readUTF();
System.out.println(value+" "+ str);
dis.close();
is.close();
}
DataOutputStream 数据输出流,适合对hava基本数据类型的输出
构造函数:
DataOutputStream (OutputStream);
api方法:
writeInt();类似这样的方法writeXXX();XXX代表具体的某种类型
/**
* DataOutputStream 数据输入流
* @throws IOException
*/
@Test
public void testMethod1() throws IOException{
//构建低级流
OutputStream os= new FileOutputStream("d:/aa/dos.txt");
//封装低级流微数据的高级流
DataOutputStream dos= new DataOutputStream(os);
dos.writeInt(1000);
dos.writeUTF("hello world");
dos.flush();
dos.close();
os.close();
}
/**
字符流:高级流
针对字符流做低级流的二次或三次封装或处理,字符流的本质还是字节流
Reader类:所有字符流的父类,是一个抽象类
-int read();
读取一个字符,是占用整形数据的低16位,低16位有效
-int read(char[] chars);
读取一个字符数组的length个字符,并存储到字符数组中
返回的是实际读取的字符量
-int read(char[] chars,int offset,int len);
读取len个字符,存储给字符数组中,以offset位置为起点
Writer类:是所有字符流的父类是一个抽象类
-void write();
写出一个字符
-void write(char[] chars);
写出一个数组的字符数据
-void write(char[] chars,int offset,int len);
写出一个数据,从offset开始,取len个字符
-void write(String str)
写出一个字符串
-void write(String str,int offset,int len)
写出字符串数据中的部分数据,以offset位置为起点.写len个
InputStreamReader类:字符输入流
-可以设置字符集,
-按照指定的字符集输入数据
-将字节按照指定的字符集读入字符串数据
-继承自Reader类
/**
* 字符的输入流
* 单字符读取
* @throws IOException
*/
@Test
public void testMethod2() throws IOException{
InputStream is= new FileInputStream("d:/aa/osw.txt");
InputStreamReader isr= new InputStreamReader(is,"utf-8");
int c=-1;
while((c=isr.read())!=-1){
System.out.println((char)c);
}
isr.close();
is.close();
}
/**
* 字符的输入流
* 多字符读取
* @throws IOException
*/
@Test
public void testMethod3() throws IOException{
InputStream is= new FileInputStream("d:/aa/osw.txt");
InputStreamReader isr= new InputStreamReader(is,"utf-8");
char[] chars= new char[3];
int len=-1;
while((len=isr.read(chars))!=-1){
System.out.println(new String(chars).substring(0,len));
}
isr.close();
is.close();
}
OutputStreamWriter类:字符输出流
-可以设置字符集,
-按照指定的字符集输入数据
-将字节按照指定的字符集写出字符串数据
-继承自Writer类
/**
* 字符输出流
* 将字节流转换成字符流
* @throws IOException
*/
@Test
public void testMethod1() throws IOException{
OutputStream os = new FileOutputStream("d:/aa/osw.txt");
OutputStreamWriter osw =new OutputStreamWriter(os,"utf-8");
osw.write("hello world,我们爱Java");
osw.flush();
osw.close();
os.close();
}
缓冲字符流:缓冲字符流自己维护一个缓冲的字符数组
BufferedReader类:缓冲字符流输入
-String readLine();//读一行数据,读到末尾为null
/**
* BufferedReader
* @throws IOException
*
*/
@Test
public void testMethod5() throws IOException{
InputStream is= new FileInputStream("d:/aa/bw.txt");
Reader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
char [] chars =new char[3];
int len = -1;
while((len=br.read(chars))!=-1){
System.out.println(new String(chars).substring(0,len));
}
br.close();
isr.close();
is.close();
}
/**
* BufferedReader
* @throws IOException
*
*/
@Test
public void testMethod6() throws IOException{
InputStream is= new FileInputStream("d:/aa/bw.txt");
Reader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
String str = "";
while((str = br.readLine())!=null){
System.out.println(str);
}
br.close();
isr.close();
is.close();
}
BufferedWriter类:缓冲字符流输出
/**
* BufferedWriter
* 先写完在读
* @throws IOException
*/
@Test
public void testMethod4() throws IOException{
OutputStream os=new FileOutputStream("d:/aa/bw.txt");
Writer osw = new OutputStreamWriter(os,"utf-8");
//第三次封装
BufferedWriter bw =new BufferedWriter(osw);
bw.write("我们爱Java,爱到天荒地老,瞎扯");
bw.flush();
bw.close();
osw.close();
os.close();
}
PrintWriter类:
-特殊的类,只有输出,没有输入
-具有自动行刷新的缓冲字符输出流
public void testMethod1() throws IOException{
OutputStream os= new FileOutputStream("d:/aa/pw.txt");
Writer osw = new OutputStreamWriter(os,"utf-8");
PrintWriter pw = new PrintWriter(osw,true);//字符,已经编码.true代表自动行刷新
//PrintWriter pw1 = new PrintWriter(os);//字节
pw.println("不是用Write写出,用println方法写出,是可以用write写出");
//pw.flush();
//pw1.close();
pw.close();
osw.close();
os.close();
}