zoukankan      html  css  js  c++  java
  • Java-IO 输入输出流详解

    一、文件的编码

                  开发时一定要注意项目默认的编码!!!!!!!!
                  文件操作的时候一定要记得关闭!!!!!!!!
           ASCII:美国标准信息交换码,用一个字节的7位可以表示一个字符
           ISO8859-1:拉丁码表,西欧标准字符集,用一个字节的8位表示
           GB2312:中文编码表,用两个字节来表示中文编码
           GBK:中文编码表的升级,融合了更多表示中文文字符号
           GB18030:GBK的取代版本
           BIG-5:同行与港台地区,是繁体字编码方案,俗称“大五码”
           Uicode:国际标准码,融合了多种文字
           UTF-8:是Unicode编码的实现方式,最多用三个字节来表示一个字符
        
           GBK编码     中文占用2个字节,英文占用1个字节
           UTF-8编码   中文占用3个字节,英文占用1个字节
           UTF-16be编码中文占用2个字节,英文占用2个字节
           Java是双字节编码 utf-16be,即java中每个字符占用两个字节
           
           当你想把一个字节序列变成一个字符串时,字节序列使用什么编码,就需要使用什么编码去显示的调用s.getBytes("字节序列的编码格式");,否则会出现乱码
     
           文本文件就是字节序列,可以是任意编码的字节序列,但是如果是在中文机器上直接创建文本文件,那么该文本文件只认识ANSI(本地编码)编码。如,新建一个TXT文件,内容为联通,打开则会出现乱码,是一种巧合,正好符合了UTF-8编码的规则
       
           Integer.toHexString(Byte);//以十六进制的方式显示
    二、File工具类的使用
             1、File类用于表示文件和目录都可以
                File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问
             2、File类的基本API(看手册)
                    构造函数的情况
                    创建功能:createNewFile(),mkdir(),mkdirs()
                    删除功能:delete()
                    重命名功能:renameTo()
                    判断功能:isFile(),isDirectory(),exists()等
                    获取功能:getName(),getPath(),list()等
                    文件过滤器的作用:list(FilenameFilter filter),返回满足指定条件的文件列表
                    
                判断参数的时候,可以使用IllegalArgumentException参数抛出异常
                File.separator设置目录分隔符,Windows、Unix都识别
                相对目录是当前目录,也即在项目的根目录下
             3、遍历目录(递归 dir.listFiles())
                访问文件系统的时候因为是与JVM以外的资源进行交互,所以,写代码一定要严谨,把各种情况考虑到了
                 
    三、RandomAccessFile类的使用
           1、RandomAccessFile java提供的对文件内容的访问,既可以读,也可以写
              且支持随机访问文件,可以访问文件的任意位置
           2、Java文件模型
                 在硬盘上的文件是byte byte byte存储的,是数据的集合
           3、打开文件 
    1 RandomAccessFile raf =newRandomAccessFile(file,"rw");//rw,读写,r只读
    2 //打开文件时,文件指针在开头,pointer = 0;
    3 raf.write(byte);//write方法只会写一个字节,同时直接指针指向下一个位置
    4 int b = raf.read();//每次读一个字节,java中每个字符占用两个字节,使用右移8位的方式分次写入
    5 raf.seek(指针位置);//移动指针
    6 raf.close();//文件读写完一定要关闭,否则可能会有意想不到的后果
    在文件下载文件的时候,这种方式有很大的好处,每个线程下载文件的一部分,
              然后再拼接在一起,迅雷就是使用的这种方式,会记录指针的位置
     
    四、字节流(InputStream、OutputStream,两个都是抽象类)
             1、I/O流用来处理设备之间的数据传输
                InputStream抽象了应用程序读取数据的方式
                OutputStream抽象了应用程序写出数据的方式
             2、EOF = End  读到 -1 就读到结尾
             3、输入流的基本方式主要是读
                  int b = in.read();//读取一个字节无符号填充到int第八位,-1是EOF
                  in.read(byte[] buf);//读入多个字节填充的字节数组
             4、输出流的基本方式主要是写
                  out.write(int b);
                  out.write(byte[] buf);
             5、FileInputStream具体实现了文件的读取操作
                    while((b=in.read())!=-1){读一个文件}
                    in.close();//一定要记得关闭流释放系统资源
                    批量读取(速度非常快,效率高) vs. 单字节读取(不适合读大文件,效率很低)
              6、FileOutputStream具体实现了向文件中写数据的操作
                    是删除文件重新创建,还是在原文件上追加内容,看构造方法
                    自己实现文件的copy操作
                    out.flush();
                    out.close();
              7、数据输入输出流DataOutputStream/DataInputStream
                    对流功能的扩展,是一个包装类,可以更加方便的读取int,long,字符等类型数据,本质是使用的一种装饰模式实现的
             8、字节缓冲流BufferedInputStream/BufferedOutputStream
                     为I/O提供了带缓冲区的操作,这种流模式提高了I/O的性能     
                     .write();
                     .flush();//刷新缓冲区,否则写入不到文件中
                     .close();
     
    五、字符流(参考API)
           1、Java为什么引入字符流?
                 操作文本时,尤其是包含中文字符等非ASCII码的字符会很不方便
                 字符流 = 字节流+编码
                 所以,要对编码问题非常清楚   
           2、java的文本(char)是16位无符号整数,是字符的Unicode编码(双字节)    
              文件是byte byte byte……的数据序列
              文本文件是文本序列按照某种编码方式序列化为byte的存储
           3、字符流(Reader Writer)操作的是文本文件
              一次处理一个字符,字符的底层仍然是基本的字节序列
              InputStreamReader 完成byte流按照编码解析为char流
              OutputStreamWriter 提供char流按照编码解析成byte流
           4、文件读写流  FileReader、FileWriter
                 没法设置编码,必须回到字符流设置编码
           5、字符流的过滤器BufferedReader、BufferedWriter、PrintWriter
                 readLine  可以一次读一行,一次写一行
                 可以设置编码,不识别换行,单独写出换行操作
     
    六、对象的序列化和反序列化
             1、将Object对象转换成byte序列,反之叫对象的反序列化
             2、序列化流(ObjectOutputStream),是过滤流---writeObject()
                反序列化流(ObjectInputStream),    ----readObject
             3、序列化接口(Serializable)
                对象必须实现序列化接口,才能进行序列化,否则将出现异常
                这个接口没有任何方法,只是一个标准,是标记接口
                
                对象序列化后,如果对再次对类文件修改,那么反序列化的时候就会出问题,那么怎么解决呢?
                需要在类中设置序列版本id,唯一标记,这样无论怎么修改读取的时候都不会再有问题   serialVersionUID
     
             4、transient关键字
                   声明的元素不会进行JVM默认的序列化,也可以自己完成这个元素的序列化
                   网络中传输时,并不是所有的元素都是有必要传输的,尤其是要考虑节约网络流量的时候
                   在有些情况下,可以帮助我们提高性能(ArrayList在数组没有放满的时候,只把有效元素序列化)
             5、序列化中 子类和父类构造函数的调用问题
                 父类实现了序列化接口,子类不需要再次实现,就能进行序列化    
                 对子类对象进行反序列化操作时,如果其父类没有显示的实现序列化接口,那么其父类的构造函数会被调用
     
    七、输入输出流的一些包装类
           1、打印流
                   PrintStream  :字节打印流
                   PrintWriter  :字符打印流
                   集成了Print()格式化输出方法,可以操作任意类型的数据
           2、标准输入输出流
                   System类的in、out字段
                   默认输入设备是键盘,输出设备是显示器
                   
                   标准IO重定向
                   System.setIn(InputStream);
                   //重定向输出可以将打印到控制台的日志写到文件
                   System.setOut(PrintStream);
                   System.err(PrintStream);
     
           3、进程控制
                  在Java内部执行其他操作系统的程序,并要求控制这些程序的输入输出时
                  向OSExecute.command()传递一个command字符串   
    Process process = new ProcessBuilder(command.split(" ")).start();
    
    OSExecute.command("javap test");
    
    //javap是java的一个反编译程序

    八、IO操作过程中异常处理

            
           自己编程要用try-catch-finally包围起来,如果有异常尽量处理,千万不要仅仅是用printStackTrace()打印栈信息,在finally中进行流的关闭(判断引用不为空的话关闭),以确保一定能得到执行
  • 相关阅读:
    project和task
    Gradle的安装
    Spring 集成 RMI
    RMI远程调用
    安装、启动与基本配置
    删除
    文件的分隔与合并
    my27_OGG MySQL To MySQL错误汇总
    1.5 GO json转Map
    1.4 Go语言-switch语句(转)
  • 原文地址:https://www.cnblogs.com/longqingyang/p/5564839.html
Copyright © 2011-2022 走看看