美文网首页
Java IO流常用类的使用方法

Java IO流常用类的使用方法

作者: Specime | 来源:发表于2018-05-12 22:04 被阅读0次

    IO继承关系

    io.jpg

    1.File类

    • File表示的是文件(目录)
    • File类只用于表示文件(目录)的信息(名称、大小等), 不能用于文件内容的访问
    • 在某些流方法中可以使用表示路径的字符串代替File对象

    构造器

    /**
     * 在不传入绝对路径的情况下,默认使用相对路径,即使用   该项目工程的路径;  
     * 目录分级使用 / 表示,也就是Linux系统的分级符(本文代码使用Windows系统环境编译)
    */
    
    //方式一:直接传入路径
    File file2 = new File("D:\\logs\\文本.txt");  
    
    //方式二:第一个参数代表父路径,第二个参数代表子路径,常用语表示某路径(第一个参数)下的某个文件(第二个参数)
    File file = new File("D:\\logs","文本.txt");
    

    常用方法

    File file = new File("");
    
    //列出当前目录下的子目录和文件名,不包含父目录名和子孙目录,返回字符串数组
    file.list();
    //返回直接子目录(文件)的抽象,表示目录的绝对路径
    file.listFiles(); 
    //判断目录或文件是否存在
    file.exists();
    //判断是否是目录
    file.isDirectory();
    //创建新目录,只创建一级
    file.mkdir();
    //创建多级目录,
    file.mkdirs();
    //判断是否是文件
    file.isFile();
    //创建新的文件
    file.createNewFile();
    //删除目录或文件
    file.delete();
    //获取绝对路径,返回String
    file.getAbsolutePath();
    //获取文件名,返回String
    file.getName()
    //获取父路径,返回String
    file2.getParent();
    

    案例

    //案例一:判断目录是否存在,存在 ? 删除 : 新建;(同理可判断文件)
       private void fileTest(File file){
            if (!file.exists()){
                file.mkdir();//只创建一级目录;file.mkdirs()可创建多级目录
            }else {
                file.delete(); //删除目录
            }
        }
        
        
    //案例二:列出指定目录下的以.java后缀结尾所有文件,包含子目录
     private void listDirectory(File dir){
            if(!dir.exists()){
                throw new IllegalArgumentException("目录"+dir+"不存在");
            }
            if (!dir.isDirectory()){
                throw new IllegalArgumentException(dir+"不是目录");
            }
            
           File[] files = dir.listFiles(); //返回直接子目录(文件)的抽象
            if (null!= files && files.length>0){
                for (File file : files){
                    if (file.isDirectory()){
                        listDirectory(file);
                    }else {
                        if (file.getName().endsWith(".java"))
                        System.out.println(file);
                    }
                }
            }
        }
    

    2、字节流

    ① InputStream、OutputStream (抽象类)

    • InputStream抽象了应用程序读取数据的方式
    • OutputStream抽象了应用程序写出数据的方式
      ② EOF = End 读到-1就到结尾
    • ③ 输入流基本方法
    • int b = in.read(); 读取一个字节无符号填充到int低八位,-1是EOF
    • in.read(byte[] buf);
    • in.read(byte[] buf,int start,int size);
    • ④ 输出流基本方法
    • out.write(int b); 写出一个字节到流,b的低八位
    • out.write(byte[] buf);将buf字节数组都写入到流
    • out.write(byte[] buf,int start,int size); buf字节数组从start开始写,写size长度
    • ⑤ FileInputStream :具体实现了在文件上读取数据

    一、 FileInputStream、FileOutputStream

    • FileInputStream:用于从文件中读取信息
    • FileOutputStream:用于将信息写入文件

    构造器

    //通过传入File对象或直接传表示路径的字符串
    FileInputStream in = new FileInputStream(new File(""));
    FileOutputStream out = new FileOutputStream(new File(""));
    
    //FileOutputStream构造器有第二个参数可选,传入boolean值,true:表示在原文件内容之后追加写入内容,  
    //false:默认值,可不传,表示清空原文件,重新写入
    

    案例

    //文件拷贝
     /**
         * 文件拷贝 (此方法效率最高)
         *
         * @param srcFile
         * @param destFile
         */
        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();
        }
    
    

    二、BufferedInputStream、BufferedOutputStream

    • BufferedInputStream:可以防止每次读取时都得进行实际写操作
    • BufferedOutputStream:可以米面每次发送数据时都要进行实际的写操作,注意: 每次写完之后调用flush()方法,以刷新缓冲区

    构造器

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); 
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
    

    案例

     /**
         * 带缓冲的文件拷贝方式(此处仅演示用法,文件拷贝不推荐使用此方式)
         *
         * 缓冲操作,一般打开文件进行写入操作或读取操作时(非拷贝),都会加上缓冲,可提高IO性能
         */
        public static void copyFileByBuffered(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();
        }
    
    

    三、DataInputStream/DataOutputStream

    • DataInputStream:与DataOutputStream搭配使用,我们可以按照可移植方式从流读取到基本数据类型
    • DataOutputStream:与DataInputStream搭配使用,我们可以按照可移植方式向流写入基本数据类型

    构造器

    DataInputStream dis = new DataInputStream(new FileInputStream(""));
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(""));
    

    案例

    • DataInputStream
    public class DisDemo {
        public static void main(String[] args) throws IOException {
            String file = "";
            DataInputStream dis = new DataInputStream(new FileInputStream(file));
            int i = dis.readInt();
            System.out.println(i);
            i = dis.readInt();
            System.out.println(i);
    
            //读取文件中 long型、double型、和utf编码字符
            long l = dis.readLong();  
            System.out.println(l);
            double d = dis.readDouble();
            System.out.println(d);
            String s = dis.readUTF();
            System.out.println(s);
    
            dis.close();
        }
    }
    
    • DataOutputStream
    public class DosDemo {
        public static void main(String[] args) throws IOException {
            String file = "demo/dos.dat";
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
            dos.writeInt(10);
            dos.writeInt(-10);
            dos.writeLong(12l);
            dos.writeDouble(12.3);
            dos.writeUTF("中国");  //采用UTF-8编码输出
            dos.writeChars("中国");  //采用Java默认的 utf-16be编码输出
    
            dos.close();
        }
    }
    

    3、字符流

    • ① 编码问题
    • ② 认识 文本和文本文件
    • Java文本:指的是char是16位无符号整数,是字符的Unicode编码(双字节编码)
    • 文本:byte byte byte...的数据序列
    • 文本文件是文本(char)序列按照某种编码方案(utf-8/gbk等)序列化为byte的存储结果
    • ③ 字符流(Reader、Writer):操作文本、文本文件
    • 字符处理,一次处理一个字符
    • 字符的底层依然是基本的字节序列
    • 字符流的基本实现:
    • InputStreamReader:完成byte流解析为char流,按照编码处理
    • OutputStreamWriter:提供char流到byte流,按照编码处理

    一、字符编码

    分类

    • ASCII(数字、英文):1个字符占一个字节(所有的编码集都兼容ASCII)
    • ISO8859-1(欧洲):1个字符占一个字节
    • GB-2312/GBK:1个字符占两个字节
    • Unicode: 1个字符占两个字节(网络传输速度慢)
    • UTF-8:变长字节,对于英文一个字节,对于汉字两个或三个字节。

    原则

    • 保证编解码方式的统一,才能不至于出现错误。

    二、InputStreamReader/OutputStreamWriter

    构造器

     FileInputStream in = new FileInputStream("D:\\logs\\文本.txt");
    InputStreamReader isr = new InputStreamReader(in,"gbk");//不写第二个参数,默认使用项目的编码格式  
            
    FileOutputStream out = new FileOutputStream("D:\\logs\\文本2.txt");
    OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
    

    案例

    /**
     *文件拷贝
     */
    public class CharStreamDemo {
        public static void main(String[] args) throws IOException {
            FileInputStream in = new FileInputStream("D:\\logs\\文本.txt");
            InputStreamReader isr = new InputStreamReader(in,"gbk");//不写第二个参数,默认使用项目的编码格式
    
            char[] buf = new char[8*1024];
            int c;
    
            FileOutputStream out = new FileOutputStream("D:\\logs\\文本2.txt");
            OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
            while ((c=isr.read(buf,0,buf.length))!=-1){
                String s = new String(buf,0,c);
                System.out.println(s);
                osw.write(buf,0,c);
                osw.flush();
            }
    
            isr.close();
            osw.close();
        }
    }
    

    三、BufferedReader/BufferedWriter/PrintWriter

    BufferedWriter和PrintWriter作用相同,PrintWriter无须刷新,可自动识别换行

    构造器

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\logs\\文本.txt"),"gbk"));
    
    BufferedWriter bw = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream("D:\\logs\\文本2.txt"),"utf-8"));
                    
    PrintWriter pw = new PrintWriter("D:\\logs\\文本3.txt");
    

    案例

    /**
     *文件拷贝
     */
    public class BrAndBwDemo {
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\logs\\文本.txt"), "gbk"));
            PrintWriter pw = new PrintWriter("D:\\logs\\文本3.txt");
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line); //一次读一行,不能识别换行
                pw.println(line); //ln自动换行
                pw.flush();
            }
    
            br.close();
            pw.close();
        }
    }
    

    四、说明

    • io包的InputStreamReader:称为从字节流到字符流的桥转换类。这个类可以设定字符转换方式。
    • OutputStreamWriter:字符到字节
      BufferedReader有readLine()使得字符输入更加方便。
    • 在I/O流中,所有输入方法都是阻塞方法。
    • BufferedWriter:给输出字符加缓冲,因为它的方法很少,所以使用父类PrintWriter,它可以使用字节流对象,而且方法很多。

    4、RandomAccessFile

    • RandomAccessFile 是Java提供的对文件内容的访问,既可以读文件也可以写文件
    • 没有继承InputStream/OutputStream抽象类
    • 支持随机访问文件,可以访问文件的任意位置
    • ①Java文件模型:在硬盘上的文件是byte byte byte存储的,是数据的集合
    • ②打开文件:有两种模式 "rw"(读写) "r"(只读)
    • RandomAccessFile raf = new RandomAccessFile(file,"rw");
    • 文件指针:打开文件时指针在开头 pointer=0;
    • ③写方法:raf.write(int) 只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
    • ④读方法:int b = raf.read(); 读一个字节
    • ⑤文件读写完成之后一定要关闭

    构造器

    RandomAccessFile raf = new RandomAccessFile(new File(""),"rw");//读写模式
    

    案例

    public class RandomDemo {
    
        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');  //只写了一个字节(后8位)
            System.out.println(raf.getFilePointer());//指针的位置
            raf.write('B');
    
            int i = 0x7fffffff;
            raf.writeInt(i);
            System.out.println(raf.getFilePointer());//指针的位置
    
            String s = "中";
            byte[] gbk = s.getBytes("gbk");
            raf.write(gbk);
            System.out.println(raf.getFilePointer());//指针的位置
    
            //读文件,把指针移到头部
            raf.seek(0);
            //一次性读取,把文件中的内容都读到字节数组中
            byte[] buf = new byte[(int) raf.length()];
            raf.read(buf);
            System.out.println(Arrays.toString(buf));
    
            for (byte b : buf) {
                System.out.println(Integer.toHexString(b & 0xff) + ""); //16进制
            }
            raf.close();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Java IO流常用类的使用方法

          本文链接:https://www.haomeiwen.com/subject/qrahdftx.html