5、java的IO操作

来源:互联网 发布:马士兵java 编辑:程序博客网 时间:2024/06/04 23:29

1、byte与String相互转化:
1.1 String转byte:
String str = “哈哈666”;
byte[] bytes = str.getBytes(“gbk”); //str转为bytes,告诉系统我要将gbk转为bytes,如果这里不声明gbk,就是用项目默认编码
1.2 byte转String:
1.2.1 不声明转码会默认用项目编码将byte转为字符串:
String str1 = new String(bytes)
System.out.println(str1)
1.2 声明编码:
String str3 = new String(bytes,’gbk’)//哈哈666
String str4 = new String(bytes,’utf8’) //乱码
String str5 = new String(bytes,’utf16be’)//乱码
【注】:如果str是GBK,就是转成字节是GBK转过去的字节bytes,如果在把bytes转出来显示也必须是转成gbk,转成其他的都会乱码

2、File类(java.io.File) :File表示文件、目录信息(名称、大小等),不能访问文件内容
2.1 常用api:
file.exists(); //文件是否存在
file.getName();//获取文件名称
file.delete(); //删除文件
file.createNewFile();//创建新文件
file.mkdir();//创建以及目录
file.mkdirs();//创建多级目录
file.getAbsolutePath();//返回文件绝对路径
file.getAbsoluteFile();//返回文件绝对路径
file.getPath();//返回文件相对路径
file.getParent();//返回父目录
file.getParentFile();//返回父文件
file.list();//返回目录所有列表

2.2 列出目录下所有文件:public void listDir(String fileDir) throws Exception{    System.out.println(fileDir);    File dir = new File(fileDir);    if(!dir.exists()){        throw new Exception("文件不存在");    }    if(!dir.isDirectory()){        throw new Exception("必须要传入一个文件夹");    }

// String filenames[] = file.list(); //返回当前目录下所有名称,字符串数组
File[] files = dir.listFiles(); //返回当前目录下所有文件,文件数组
if(files != null && files.length > 0){
for(File file : files){
if(file.isDirectory()){
this.listDir(file.getAbsolutePath());
}else{
System.out.println(fileDir + ‘/’ + file.getName());
}
}
}
}

3、RandomAccessFile:既可以读取文件内容,又可以写文件,并且可以随机访问文件,访问文件任何位置
3.1 硬盘上的文件是byte、byte、byte存储的,是数据的集合
3.2 打开文件有两种方式:
rw(读写)、r(读)
RandomAccessFile raf = new RandomAccessFile(file,’rw’);
打开文件时,指针在开头poiner = 0
3.3 写方法
raf.write(int) —–>只写一个字节(后8bit),同时指针指向下个位置,准备写入
3.4 读方法
int b = raf.read()—>都一个字节
3.5 文件读写完成后一定要关闭

4、IO流(输入、输出流)
4.1 字节流:
4.1.1 InputStream、OutputStream(都是抽象类)
InputStream:抽象了应用程序读取数据的方式
OutputStream抽象了应用程序写出数据的方式
4.1.2 结束:EOF=End 读到-1就读到结尾
4.1.3 输入流基本方法
int b = in.read();读取一个字节无符号填充到int第8位,-1是EOF
in.read(byte[] buf);读取数据直接填充到字节数组
in.read(byte[] buf,int start,int size);读取数据直接填充到字节数组,从start开始放,放多少size长度的数据
4.1.4 输出流基本方法
out.write(int b) 写出一个byte到流,b的第8位
out.write(byte[] buf);
out.write(byte[] buf,int start,int size);
4.1.5 FileInputStream:具体实现了在文件上读取数据到内存
FileOutputStream:从内存读取到文件
创建:FileOutputStream out = new FileOutputStream(“E:/aa.dat”);
追加:FileOutputStream out = new FileOutputStream(“E:/aa.dat”,true); //如果第二个参数不传true,则被清空

            【FileInputStream事例】从文件中读取            方法一:一个一个字节读取            /**             * 一个一个字节读取,读取指定文件内容,按照16进制输出到控制台,并且每输出10bit换行             * @param dir             * @throws Exception             */            public void test(String filename) throws Exception{                //把文件作为字节流进行操作                FileInputStream in = new FileInputStream(filename);                int b;                int i = 1;                while((b = in.read()) != -1){  //一次一个字节                    System.out.println(Integer.toHexString(b)+" ");                    if(i++ % 10 == 0){                        System.out.println("\n");                    }                }            }            方法二:一块一块读取            /**             * 批量读取,开辟内存读取一块一块读取,非一个一个字节读取,读取指定文件内容,按照16进制输出到控制台,并且每输出10bit换行             * @param dir             * @throws Exception             */            public void test(String filename) throws Exception{                FileInputStream in = new FileInputStream(filename);                byte[] buf = new byte[20*1024]; //暂时缓冲                //从in中批量读取字节吗放入到buf这个字节数组中,从第0个位置开始放,最多放buf.length个,返回的是读到的字节个数                int bytes = 0;                int j = 1;                while((bytes = in.read(buf,0,buf.length)) != -1){                    for(int i=0;i<bytes;i++){                        System.out.println(Integer.toHexString(buf[i])+" ");                        if(j++ % 10 == 0){                            System.out.println("\n");                        }                    }                }            }            【FileOutputStream事例】向文件中写入            创建:FileOutputStream out = new FileOutputStream("E:/aa.dat");            追加:FileOutputStream out = new FileOutputStream("E:/aa.dat",true); //如果第二个参数不传true,则被清空            方法一:一个字节一个字节写入:            /**             * 拷贝文件             * @param src             * @param des             * @throws Exception             */            public void copyFile(File src,File des) throws Exception{                if(!src.isFile()){                    throw new Exception("src不是一个文件");                }                FileInputStream in = new FileInputStream(src);                FileOutputStream out = new FileOutputStream(des);                int b ;                while( (b= in.read()) != -1){ //读取文件到buf(缓冲区)                    out.write(b);//从buf(缓冲区)读取出来写到文件                    out.flush();//手动清空缓冲数据                }                in.close();                out.close();            }             方法二:批量写入            /**             * 批量写入文件             * 拷贝文件             * @param src             * @param des             * @throws Exception             */            public void copyFile(File src,File des) throws Exception{                if(!src.isFile()){                    throw new Exception("src不是一个文件");                }                FileInputStream in = new FileInputStream(src);                FileOutputStream out = new FileOutputStream(des);                byte[] buf = new byte[8*1024];                int b ;                while( (b= in.read(buf,0,buf.length)) != -1){ //读取文件到buf(缓冲区)                    out.write(buf,0,b);//从buf(缓冲区)读取出来写到文件                    out.flush();//手动清空缓冲数据                }                in.close();                out.close();            }    4.1.6  DataOutputStream、DataInputStream (就是对FileOutputStream\FileInputStream包装了一层):对"流"功能的扩展,可以更方便读取int、long、字符等类型数据        4.1.6.1 DataOutputStream:               writeInt()\writeDouble()\writeUTF()//UTF:中文汉字以utf8编码输出            事例:                String file = "E:/www/test66";                DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));                dos.writeInt(10);                dos.writeInt(-10);                dos.writeLong(10l);                dos.writeDouble(10.8);                dos.writeUTF("牛逼");//以UTF-8形式写出                dos.close();        4.1.6.2 DataInputStream:            readInt()\readDouble()\readUTF()//UTF:中文汉字以utf8编码输出            事例:                    String file = "E:/www/test66";                    DataInputStream dis = new DataInputStream(new FileInputStream(file));                    int i1 = dis.readInt();                    System.out.println(i1);                    int i2 = dis.readInt();                    System.out.println(i2);                    long i3 = dis.readLong();                    System.out.println(i3);                    Double i4 = dis.readDouble();                    System.out.println(i4);                    String i5 = dis.readUTF();                    System.out.println(i5);    4.1.7 BufferedInputStream、BufferedOutputStream:为IO读写提供了缓冲区,性能更高          性能高体现:          从应用程序中把输入放入文件,相当于把一缸水到入另一缸中:          FileOutputStream->wirte :相当于一滴一滴转移          DataOutputStream->writeXxx:相当于一瓢一瓢转移          BufferedOutputStream->write:相当于一瓢一瓢先放入桶(缓冲)中,然后一起把桶中的倒入缸中        利用缓冲区写入        /**         * 拷贝文件         * @param src         * @param des         * @throws Exception         */        public void test(File src,File des) throws Exception{            if(!src.isFile()){                throw new Exception("src不是一个文件");            }            BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(des));            int b ;            while( (b= in.read()) != -1){ //读取文件到buf(缓冲区)                out.write(b);//从buf(缓冲区)读取出来写到文件                out.flush();//刷新缓冲区            }            in.close();            out.close();        }4.2 字符流      4.2.1 编码问题    4.2.2 认识文本和文本文件:        4.2.2.1 java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)文件是byte byte byte...的数据序列        4.2.2.2 文本文件是文本(char)按照某种编码方案(utf-8、utf-16be、gbk..)序列化为byte存储的    4.2.3 字符流(Reader\Writer):操作的是文本文件        字符处理:一次处理一个字节,字符底层依然是基本的字节序列        字符流基本实现:            InputStreamReader   完成byte流解析为char流,按照编码解析            OutputStreamWrite   提供char流到byte流,按照编码处理            事例:            【读取文件操作】:            FileInputStream in = new FileInputStream("E:/www/MyEclipse10/note.java");            InputStreamReader isr = new InputStreamReader(in,"utf-8"); //如果note.java是utf-8,那这里就要设置utf-8,否则读出来就是乱码,不写的话默认是项目编码            int b;    //      //一次读一个字符    //      while((b = isr.read()) != -1){    //          System.out.println((char)b);    //      }            //批量读取            char[] buffer = new char[8*1024];//一次读8M            while((b = isr.read(buffer,0,buffer.length)) != -1){                String s = new String(buffer,0,b);                System.out.println(s);            }            【读取、写入】            //获取InputStreamReader对象            FileInputStream in = new FileInputStream("E:/www/MyEclipse10/note.java");            InputStreamReader isr = new InputStreamReader(in,"gb2312");            //获取OutputStreamWriter对象            FileOutputStream out = new FileOutputStream("E:/www/MyEclipse10/note2.java");            OutputStreamWriter osw = new OutputStreamWriter(out,"gb2312");            //批量读取、写入            int b;            char[] buffer = new char[8*1024];//一次读8M            while((b = isr.read(buffer,0,buffer.length)) != -1){                osw.write(buffer, 0, b);                osw.flush();            }            isr.close();            osw.close();    4.2.4 FileReader\FileWrite:专门处理文件的            【注】:无法设置读、取编码,只能根据项目便来来读取            FileReader fr = new FileReader("E:\\www\\MyEclipse10\\note2.java");            FileWriter fw = new FileWriter("E:\\www\\MyEclipse10\\note4.java",true); //第二个参数true是追加            char[] buffer = new char[2048];            int b ;            while((b = fr.read(buffer,0,buffer.length))!=-1){                fw.write(buffer,0,b);                fw.flush();            }            fr.close();            fw.close();        }    4.2.5 字符流过滤器(BufferedReader、BufferedWriter):        【读取、写入】        方法一:        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:/www/MyEclipse10/note2.java")));        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/www/MyEclipse10/note3.java")));        String line;        while((line = br.readLine()) != null){ //一次读取一行,不会自动加换行            System.out.println(line);            bw.write(line);            bw.newLine(); //换行操作            bw.flush();        }        br.close();        bw.close();        方法二:使用PrintWriter替代BufferedWriter        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:/www/MyEclipse10/note2.java")));//      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/www/MyEclipse10/note3.java")));        PrintWriter pw = new PrintWriter("E:/www/MyEclipse10/note4.java");        String line;        while((line = br.readLine()) != null){ //一次读取一行,不会自动加换行            System.out.println(line);            pw.println(line); //换行直接println,不换行print            pw.flush();        }        br.close();        pw.close();

5、序列化:
5.1 对象序列化、反序列化
5.2 对象序列化,就是将Object转换成bytexulie,反之叫对象的反序列化
5.3 序列化流(ObjectOutputStream),是过滤流—writeObject
反序列化流(ObjectInputStream),是过滤流—readObject
5.4 序列化接口(Serializable)
对象序列化必须实现接口Serializable,才能进行序列化,否则将出现异常,这个接口没有任何方法,只是一个标准

  【事例】    public class Student implements Serializable{        private String stuno;        private String stuname;        private int stuage;        public Student(){        }        public Student(String stuno,String stuname,int stuage){            this.stuno = stuno;            this.stuname = stuname;            this.stuage = stuage;        }        public String getStuno() {            return stuno;        }        public void setStuno(String stuno) {            this.stuno = stuno;        }        public String getStuname() {            return stuname;        }        @Override        public String toString() {            return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage="                    + stuage + "]";        }        public void setStuname(String stuname) {            this.stuname = stuname;        }        public int getStuage() {            return stuage;        }        public void setStuage(int stuage) {            this.stuage = stuage;        }    }    //序列化保存    String file = "E:/www/MyEclipse10/stu.dat";    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));    Student stu = new Student("1001","张三",20);    oos.writeObject(stu);    oos.flush();    oos.close();    //反序列化读取    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));    Student oldstu = (Student)ois.readObject();    ois.close();    System.out.println(oldstu.getStuage());    System.out.println(oldstu.getStuname());    System.out.println(oldstu.getStuno());5.5 transient  : transient修饰的属性,不会被jvm默认序列化,可以自己完成序列化    例子:private transient int stuage;    public class Student implements Serializable{        private String stuno;        private String stuname;        private transient int stuage; //本来不会在jvm默认序列化,但是writeObject、readObject会使其序列化        public Student(){        }        public Student(String stuno,String stuname,int stuage){            this.stuno = stuno;            this.stuname = stuname;            this.stuage = stuage;        }        public String getStuno() {            return stuno;        }        public void setStuno(String stuno) {            this.stuno = stuno;        }        public String getStuname() {            return stuname;        }        @Override        public String toString() {            return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage="                    + stuage + "]";        }        public void setStuname(String stuname) {            this.stuname = stuname;        }        public int getStuage() {            return stuage;        }        public void setStuage(int stuage) {            this.stuage = stuage;        }        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{            s.defaultWriteObject();//将jvm能序列化的都给序列化            s.writeInt(this.stuage); //自定义序列化        }        private void readObject(java.io.ObjectInputStream s) throws java.io.IOException,ClassNotFoundException{            s.defaultReadObject(); //将jvm能反序列化的都给反序列化            this.stuage = s.readInt(); //自定义反序列化        }    }5.6 序列化中父类与子类构造方法的问题:序列化中如果父类序列化了,子类就不需要序列化  5.6.1 :子类序列化时,父类、子类都会调用构造方法  5.6.2 : 反序列化时,如果父类没有实现序列化接口,会调用父类构造方法,如果父类实现了序列化接口,则父类不会被调用构造方法
原创粉丝点击