zoukankan      html  css  js  c++  java
  • Java--I/O输入输出流

    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<bytes;i++){
                if(buf[i]<=0xf){
                    System.out.print("0");
                }
                System.out.print(Integer.toHexString(buf[i])+" ");
                if(j++%10==0){
                    System.out.println();
                }
            }
            in.close();
        }
    
    }

     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...");
        }
    }
  • 相关阅读:
    AngularJs 1.x和AngularJs2的区别
    AngularJS ui-router (嵌套路由)
    $scope.$apply
    AngularJS中的$watch(),$digest()和$apply()区分
    对比jQuery和AngularJS的不同思维模式
    angular.element 动态添加和删除元素
    [Leetcode] Integer to Roman
    [Leetcode] Longest Common Prefix
    [Leetcode] Plus One
    [Leetcode] Palindrome Number
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/6404488.html
Copyright © 2011-2022 走看看