博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java--I/O输入输出流
阅读量:6232 次
发布时间:2019-06-21

本文共 11603 字,大约阅读时间需要 38 分钟。

1、编码问题

package com.imooc_io;public class CodeTest {    public static void main(String[] args) throws Exception{               String s = "慕课ABC";        byte[] bytes1 = s.getBytes();//转换成字节序列用的是项目默认的编码        for(byte b:bytes1){            //把字节转换成了int以16进制的方式显示            System.out.print(Integer.toHexString(b & 0xff)+" ");        }        System.out.println();        //gbk编码中文占用两个字节,英文占用一个字节                byte[] bytes2 = s.getBytes("utf-8");        //utf-8编码中文占用3个字节,英文占用一个字节        for(byte b:bytes2){            System.out.print(Integer.toHexString(b & 0xff)+" ");        }        System.out.println();        //java是双字节编码utf-16be        byte[] bytes3 = s.getBytes("utf-16be");        //utf-16be编码中文占用2个字节,英文占用2个字节        for(byte b:bytes3){            System.out.print(Integer.toHexString(b & 0xff)+" ");        }        System.out.println();        String str1 = new String(bytes3);//乱码        String str2 = new String(bytes3,"utf-16be");        System.out.println(str1);        System.out.println(str2);    }}

2、File类

用于表示文件或目录的信息,不能用于文件内容的访问

package com.imooc_io;import java.io.File;import java.io.IOException;public class FileDemo {    public static void main(String[] args) {        File file = new File("D:\\imooc\\jsp");        System.out.println(file.exists());        if(!file.exists()){            file.mkdir();        }else{            file.delete();        }        System.out.println(file.isDirectory());        System.out.println(file.isFile());                File file2 = new File("D:\\imooc\\1.txt");        //File file2 = new File("D:\\imooc","1.txt");        if(!file2.exists()){            try {                file2.createNewFile();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }else{            file2.delete();        }        //常用的File对象方法        System.out.println(file.getAbsolutePath());        System.out.println(file.getName());        System.out.println(file.getParent());        System.out.println(file.getParentFile().getAbsolutePath());            }}

 遍历目录:

package com.imooc_io;import java.io.*;public class FileUtils {    /**     * 列出指定目录下(包括其子目录)的所有文件     * @throws IllegalAccessException      */    public static void listDirectory(File dir)throws IOException, IllegalAccessException{        if(!dir.exists()){            throw new IllegalAccessException("目录:"+dir+"不存在");        }if(!dir.isDirectory()){            throw new IllegalAccessException(dir+"不是目录");        }        //直接子的名称,不包含子目录下的文件        /**        String[] filenames = dir.list();        for(String string : filenames){            System.out.println(dir+"\\"+string);        }         */        //如果要遍历子目录下的内容就需要构造File对象做递归操作        File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象//        for(File file:files){//            System.out.println(file);//        }        if(files!=null&&files.length>0){            for(File file:files){                if(file.isDirectory()){                    listDirectory(file);                }else{                    System.out.println(file);                }            }        }    }}

3、RandomAcessFile

Java提供的对文件内容的访问,既可以读文件也可以写文件

支持随机访问文件,可以访问文件的任意位置

 Java文件模型

在硬盘上的文件是byte存储的,是数据的集合

打开文件

有两种模式"rw","r"

RandomAccessFile raf = new RandomAccessFile(file,"rw");

文件指针,打开文件时在开头pointer = 0;

 

package com.imooc_io;import java.io.*;import java.lang.reflect.Array;import java.util.Arrays;public class RafDemo {    public static void main(String[] args) throws IOException {                File demo = new File("demo");        if(!demo.exists()){            demo.mkdir();        }        File file = new File(demo,"raf.dat");        if(!file.exists()){            file.createNewFile();        }                RandomAccessFile raf = new RandomAccessFile(file, "rw");        //指针的位置        System.out.println(raf.getFilePointer());        raf.write('A');//只写一个字节        int i = 0x7fffffff;//java最大整数        //如果要把i写进去写4次        raf.write(i>>>24);//高8位        raf.write(i>>>16);        raf.write(i>>>8);        raf.write(i);        System.out.println(raf.getFilePointer());                //可以直接写一个int        raf.writeInt(i);                //读文件,必须把指针移到头部        raf.seek(0);        //一次性读取,把文件的内容都读到字节数组中        byte[] buf = new byte[(int) raf.length()];        raf.read(buf);        System.out.println(Arrays.toString(buf));    }}

4、字节流FileInputStream

具体实现了在文件上读取数据

输入流基本方法

int b = in.read();读取一个字节无符号填充到int低8位。-1是EOF结尾的意思

in.read(byte[] buf);读取数据填充到字节数组buf

in.read(byte[] buf ,int start,int size);

输出流基本方法

out.write(int b)

out.write(byte[] buf)

out.write(byte buf , int start,int size);

package com.imooc_io;import java.io.FileInputStream;import java.io.IOException;public class IOUtil {    /**     * 读取指定文件内容,按照16进制输出到控制台     * 并且没输出10个byte换行     * @throws IOException      */        public static void printHex(String fileName) throws IOException{        //把文件作为字节流进行操作        FileInputStream in = new FileInputStream(fileName);        int b ;        int i= 1;        while ((b=in.read())!=-1) {            if(b<=0xf){
//b小于1位数 //单位数前面补0 System.out.print("0"); } //将整型b转换为16进制表示的字符串 System.out.print(Integer.toHexString(b)+" "); if(i++%10==0){ System.out.println(); } } in.close(); } public static void printHexByByteArray(String fileName) throws IOException{ FileInputStream in = new FileInputStream(fileName); byte[] buf = new byte[20*1024]; int bytes = in.read(buf, 0, buf.length); int j = 1; for(int i =0;i

 5、字节输出流FileOutputStream

//如果该文件不存在,则直接创建,如果存在,删除后创建

FileOutputStream out = new FileOutputStream("demo/out.dat");

public static void copyFile(File srcFile,File destFile) throws IOException{        if(!srcFile.exists()){            throw new IllegalArgumentException("文件"+srcFile+"不存在");        }        if(!srcFile.isFile()){            throw new IllegalArgumentException(srcFile+"不是文件");        }        FileInputStream in = new FileInputStream(srcFile);        FileOutputStream out = new FileOutputStream(destFile);                byte[] buf = new byte[8*1024];        int b ;        while((b=in.read(buf, 0, buf.length))!=-1){            out.write(buf, 0, b);            out.flush();        }        in.close();        out.close();    }

 DataOutputStream/DataIntputStream

对“流”功能的扩展,可以更加方便的读取int, long,字符等类型数据

DataOutputStream:writeInt()/writeDouble()/writeUTF()

DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));

6、字节缓冲流BufferedInputStream/BufferedOutputStream

这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IIO的性能

public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{        if(!srcFile.exists()){            throw new IllegalArgumentException("文件"+srcFile+"不存在");        }        if(!srcFile.isFile()){            throw new IllegalArgumentException(srcFile+"不是文件");        }        BufferedInputStream bis = new BufferedInputStream(                new FileInputStream(srcFile));        BufferedOutputStream bos = new BufferedOutputStream(                new FileOutputStream(destFile));        int c;        while((c=bis.read())!=-1){            bos.write(c);            bos.flush();        }        bis.close();        bos.close();    }

 7、字符流

Java的文本(char)是16位无符号整数,是字符的Unicode编码(双字节编码)

文件是byte、byte、byte。。。的数据序列

文本文件是文本(char)序列按照某种编码方案序列化为byte的存储结构

字符流(Reader/Writer):处理文本文本文件

字符的处理,一次处理一个字符

字符的底层任然是基本的字节序列

字符流的基本实现

InputStreamReader 完成byte流解析为char流,按照编码解析

OutputStreamWriter 提供char流到byte流,有编码处理

public static void main(String[] args) throws IOException {        FileInputStream in =new FileInputStream("D:\\Java open source\\API\\javascript\\JavaScript方法大全.txt");        InputStreamReader isr = new InputStreamReader(in,"UTF-8");        FileOutputStream out = new FileOutputStream("D:\\Java open source\\API\\javascript\\JavaScript方法大全2.txt");        OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");        //        int c;//        while((c = isr.read())!=-1){//            System.out.print((char)c);//        }        char[] buf = new char[8*1024];        int c;        //批量读取,放入buffer这个字符数组,从第0个位置开始的位置,最多放buf.length        //返回的是读到字符的个数        while ((c = isr.read(buf,0,buf.length))!=-1) {            String s = new String(buf,0,c);            System.out.print(s);            osw.write(buf, 0, c);        }        in.close();        out.close();        isr.close();        osw.close();    }

 FileReader/FileWriter没有编码参数,有编码问题时,还是要回归上面方法

字符流的过滤器

BufferedReader  --->readLine一次读一行

BufferedWriter/PrintWriter

public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(                new InputStreamReader(                        new FileInputStream("D:\\Java open source\\API\\javascript\\1.txt")));//        BufferedWriter bw = new BufferedWriter(//                new OutputStreamWriter(//                        new FileOutputStream("D:\\Java open source\\API\\javascript\\2.txt")));        PrintWriter pw = new PrintWriter("D:\\Java open source\\API\\javascript\\3.txt");        String line;        while((line = br.readLine())!=null){            System.out.println(line);//一次读一行,并不能识别换行//            bw.write(line);//            //单独写出换行//            bw.newLine();//            bw.flush();            pw.println(line);            pw.flush();        }        br.close();//        bw.close();        pw.close();    }

 8、对象的序列化和反序列化

对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化

序列化流(ObjectOuputStream),是过滤流---WriteObject

反序列化流(ObjectInputStream)---readObject

序列化接口(Serializable)

对象必须实现序列化接口,才能进行序列化,否则将出现异常

这个接口,没有任何方法,只是一个标准

public class Student implements Serializable{    private static final long serialVersionUID = 1L;public static void main(String[] args) throws IOException{        String file="demo/obj.dat";        //对象序列化        ObjectOutputStream oos = new ObjectOutputStream(                new FileOutputStream(file));        Student stu = new Student("100001","zhangsan","20");        oos.writeObject(stu);        oos.flush();        oos.close();

      ObjectInputStream ois = new ObjectInputStream(

          new FileInputStream(file));
      Student stu1 = (Student) ois.readObject();
      ois.close();

}

希望对象能在网络进行传输,在网络进行传输是以字节为单位,需要把对象序列化成字节,所以需要序列化

transient关键字:

private transient int stuage;//该元素不会被jvm默认的序列化,也可以自己完成这个元素序列化

有些元素在网络传输中不需要序列化,如果还序列化则会浪费资源

分析ArrayList的序列化和反序列化源码。

序列化中子父类构造函数的调用问题:

package com.imooc_io;import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.Serializable;public class ObjectserialDemo {    public static void main(String[] args) throws IOException, Exception{//        ObjectOutputStream oos = new ObjectOutputStream(//                new FileOutputStream("demo/obj1.dat"));//        Foo2 foo2 = new Foo2();//        oos.writeObject(foo2);//        oos.flush();//        oos.close();        //反序列化是否递归调用父类的构造函数        ObjectInputStream ois = new ObjectInputStream(                new FileInputStream("demo/obj1.dat"));        Foo2 foo2 = (Foo2) ois.readObject();        //发现没有调用构造函数,只是打印了这个对象        System.out.println(foo2);        ois.close();    }}/***一个类实现了序列化接口,那么其子类都可以进行序列化*对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,*那么其父类的构造函数会被调用*序列化了,构造函数不会被调用*/class Foo implements Serializable{    public Foo(){        System.out.println("foo...");    }}class Foo1 extends Foo{    public Foo1(){        System.out.println("foo1...");    }}class Foo2 extends Foo1{    public Foo2(){        System.out.println("foo2...");    }}

 

转载于:https://www.cnblogs.com/Nyan-Workflow-FC/p/6404488.html

你可能感兴趣的文章
C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举
查看>>
IOS UIWebView使用开发
查看>>
redis 常用命令
查看>>
微软将Office语音办公啦
查看>>
设计模式(一)
查看>>
3分钟理解响应式布局
查看>>
LeCun再度回应卸任:我没有被取代,Jérôme 的朋友爆料趣事
查看>>
【零基础】PostgreSQL从入门到精通
查看>>
JavaScript的childNodes、nodeType、nodeValue属性
查看>>
sublime 常用python 插件
查看>>
美丽播直播直播系统解决方案:1000在线服务器方案
查看>>
truffle环境搭建
查看>>
微信官方接口文件
查看>>
Redis客户端细解、持久化
查看>>
玩转ActiveMQ与Zookeeper集群
查看>>
SAP CRM中间件下载equipment时遇到的一个错误
查看>>
Tomcat+Servlet面试题都在这里
查看>>
20180227,工作总结
查看>>
区块链100讲:详解区块链之P2P网络
查看>>
以太坊区块链技术开发岗位面试题集锦,附答案
查看>>