zoukankan      html  css  js  c++  java
  • IO系列之三: 常见操作

    一,File类

    File类位于java.io包下,用来表示文件(目录)。

    File类只用于表示文件(目录)的信息(文件名称,文件大小),不能用于文件内容的访问

    1,File的基本操作

    package com.amazing.jdk.learn2IO_0821.FileAPI;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     * Created by yaming on 17-8-21.
     */
    public class FileDemo {
        public static void main(String[] args) {
            //window,linux系统文件分割符不同,可以使用File.separator设置分隔符。适用window和linux
            File fileSeparator=new File("e:"+File.separator+"javaio"+File.separator+"test");
    
    
            /**
             * 1,操作目录
             */
            File file=new File("/home/yaming/Desktop/filedemo");
    
            //查看目录是否存在,不存在就创建
            System.out.println(file.exists());
    
            if(!file.exists())
                file.mkdir();
            else
                file.delete();
    
            //判断是否是一个目录,如果是目录返回true.如果不是目录或目录不存在,返回false
            boolean flag1 = file.isDirectory();
    
            //判断是否是一个文件
            boolean flag2 = file.isFile();
    
    
            /**
             * 操作文件
             */
            //判断文件是否存在
            File file2=new File("/home/yaming/Desktop/日记.txt");
            //不存在就创建文件
            if (!file2.exists()){
                try {
                    file2.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else {
                file2.delete();
            }
    
    
            /**
             * 常用File对象的API
             */
    
            //打印file,打印的是file.toString()的内容
            System.out.println(file);
    
            //目录绝对路径
            System.out.println(file.getAbsoluteFile());
    
            //打印目录最后一级的名字
            System.out.println(file.getName());
    
            //打印文件名字
            System.out.println(file2.getName());
    
            //访问父目录,目录路径
            String parentPath = file.getParent();
    
        }
    }

    2,File类常用操作

    遍历目录:

    package com.amazing.jdk.learn2IO_0821.FileAPI;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     * Created by yaming on 19-5-4.
     */
    public class FileUtils {
    
    
        /**
         * 列出指定目录下(包括子目录)的所有文件
         * @param dir
         * @throws IOException
         */
        public static void listDirectory(File dir)throws IOException{
    
            if(!dir.exists()){
                throw new IllegalArgumentException("目录不存在");
            }
    
            if (!dir.isDirectory()){
                throw new IllegalArgumentException(dir+"不是目录");
            }
    
            File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象
            if (files != null && files.length >0){
                for (File file : files){
                    if (file.isDirectory()){
                        //递归
                        listDirectory(file);
                    }else {
                        System.out.println(file);
                    }
                }
            }
        }
    }

    二,RandomAccessFile类的使用

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

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

    1,java文件模型:

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

    2,打开文件

      有两种模式  "rw"(读写模式), "r" (只读模式)

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

      文件指针,打开文件时指针在开头 pointer = 0; 读写操作后,指针向后移动(写和读的时候指针都会移动)

    3,写方法

      raf.write(int) ---->只写一个字节(后8位),同时指针指向下一个位置,然后再次写入

    4,读方法

      int b = raf.read() ----> 读一个字节

    5,文件读写完成后一定要关闭

    6,代码:

    package com.amazing.jdk.learn2IO_0821.FileAPI;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.Arrays;
    
    /**
     * Created by yaming on 19-5-4.
     */
    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');//只写了一个字节
            System.out.println(raf.getFilePointer());
            
            raf.write('B');
            
            
            int i = 0x7fffffff;//这是最大的整数
            //写一个Int值,用write方法每次只能写一个字节,如果要把i写进去就得写4次
            raf.write(i >>> 24);//高8位
            raf.write(i >>> 14);//高8位
            raf.write(i >>> 8);//高8位
            raf.write(i);//最低8位
    
            System.out.println(raf.getFilePointer()); //打印:6
            
            
            //可以直接写一个int
            raf.writeInt(i);
            
            
            //写中文
            String s = "";
            byte[] gbk = s.getBytes("gbk");
            //转成gbk,一个汉字两个字节
            raf.write(gbk);
            System.out.println(raf.length());//打印:12
    
    
            /**
             * 读文件
             * 
             */
            //1,必须把指针移动到头部
            raf.seek(0);
            //一次性读取,把文件中的内容都读取到字节数组中
            byte[] buf = new byte[(int) raf.length()];
            raf.read(buf);
            System.out.println(Arrays.toString(buf));
            
        }
    }

     三,字节流

    1,文件输入流

    1.1,InputStream,OutputStream

      InputStream抽象了应用程序读取数据的方式

      OutputStream抽象了应用程序写出数据的方式

    1.2,EOF = end 读到-1就读到结尾

    1.3,输入流基本方法

    我们把键盘作为一个文件,键盘是输入,比如往记事本里写数据。实际上是从键盘文件读取了数据,然后写入到了txt文件。

    所以键盘是一个输入文件,是用来读的。我们从键盘上读的东西,写到了文本文件里。所以输入流的基本方法是读

    int b = in.read();读取一个字节,无符号填充到int的低八位,高八位补零。 -1是EOF

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

    in.read(byte[],int start,int size);读取数据到字节数组buf中,从buf的start位置开始,存放size长度的数据

    1.4,输出流基本方法

    out.write(int b);写出一个byte到流,b的低8位。

    out.write(byte[] buf);将buf字节数组都写入到流

    out.write(byte[] buf ,int start, int size);字节数组buf从start位置开始写size长度的字节到流

    1.5,FileInputStream --->具体实现了在文件上读取数据

    代码:

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.*;
    
    /**
     * Created by yaming on 17-8-21.
     * 工具类
     */
    public class IOUtils {
        /**
         *需求:读取指定文件内容,按照16进制输出到控制台
         * 并且每输出10个byte换行。读到最后一个
         */
        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){
                    //单位的数补零
                    System.out.print("0");
                }
                //将整形b转换成16进制表示的字符串
                System.out.print(Integer.toHexString(b)+" ");
                if(i++%10==0){
                    //换行
                    System.out.println();
                }
    
            }
            //IO操作后必须关闭
            in.close();
    
        }
    
    }

     1.6,FileOutputStream --->实现了向文件中写出byte数据的方法

     拷贝文件代码:

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.*;
    
    /**
     * Created by yaming on 17-8-21.
     * 工具类
     */
    public class IOUtils {
    
        /**
         * 文件拷贝,字节批量读取
         * 拷贝速度最快
         * 复制文件功能,一个是读操作,另一个是写操作
         * @param srcFile
         * @param destFile
         */
        public static void copyFile(File srcFile,File destFile)throws IOException{
            //文件不存在
            if(!srcFile.exists()){
                throw new IllegalArgumentException("文件"+srcFile+"不存在");
    
            }
            if(!destFile.exists()){
                throw new IllegalArgumentException(destFile+"不是文件");
            }
    
            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();
    
        }
    
       
        /**
         * 文件拷贝,单字节不带缓冲
         * 拷贝速度最慢
         * @param srcFile
         * @param destFile
         */
        public static void copyFileByByte(File srcFile,File destFile)throws IOException{
            //文件不存在
            if(!srcFile.exists()){
                throw new IllegalArgumentException("文件"+srcFile+"不存在");
    
            }
            if(!destFile.exists()){
                throw new IllegalArgumentException(destFile+"不是文件");
            }
            FileInputStream fis=new FileInputStream(srcFile);
            FileOutputStream fos=new FileOutputStream(destFile);
            int d;
            while ((d=fis.read())!=-1){
                fos.write(d);
                fos.flush();//也可以不刷新
            }
            fis.close();
            fos.close();
    
        }
    
    
    }

    1.7,DataOutputStream / DataInputStream

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

    比如:writeInt() / writeDouble / writeUTF()

    示例代码:

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.*;
    
    /**
     * Created by yaming on 17-8-22.
     */
    public class DataStream {
        public static void main(String[] args)throws IOException {
            String file="/home/yaming/Desktop/test";
            DataOutputStream dos=new DataOutputStream(new FileOutputStream(file));
            dos.writeInt(10);
            dos.writeInt(-10);//对write方法进行了包装
            dos.writeDouble(1.7);
            //采用utf-8编码写出
            dos.writeUTF("中国");
            //utf-16be编码
            dos.writeChars("中国");
            dos.close();
            IOUtils.printHex(file);
            System.out.println();
            DataInputStream dis=new DataInputStream(new FileInputStream(file));
            int i=dis.readInt();//对read方法进行了包装
            System.out.println(i);
            i=dis.readInt();
            System.out.println(i);
            double d=dis.readDouble();
            System.out.println(d);
            String s=dis.readUTF();
            System.out.println(s);
            dis.close();
        }
    }

     1.7,BufferedInputStreamBufferedOutputStream

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

    从应用程序中把输入放入文件,相当于将一缸水倒入另外一个缸中;

    FileOutputStream ----->write()方法相当于一滴一滴的把水 转移 过去

    DataOutputStream ----->writeXxx()方法会方便一些,相当于一瓢一瓢的把水 转移 过去

    BufferedOutputStream ---->write方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高

    代码:

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.*;
    
    /**
     * Created by yaming on 17-8-21.
     * 工具类
     */
    public class IOUtils {
    
        /**
         * 文件拷贝,利用带缓冲的字节流
         * 复制文件功能,使用buffer缓冲区
         * @param srcFile
         * @param destFile
         */
        public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
            //文件不存在
            if(!srcFile.exists()){
                throw new IllegalArgumentException("文件"+srcFile+"不存在");
    
            }
            if(!destFile.exists()){
                throw new IllegalArgumentException(destFile+"不是文件");
            }
    
            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();
    
        }
    
    }

     四,字符流

    1,认知文本和文本文件

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

    文件是byte byte byte ....的数据序列

    文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结构

    2,字符流(Reader, Writer)

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

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

    3,字符流的基本实现

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

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

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * Created by yaming on 17-8-23.
     */
    public class IsrAndOswDemo {
        public static void main(String[] args)throws IOException {
            FileInputStream fis=new FileInputStream("/home/yaming/Desktop/今天");
            //操作文本文件,操作一个mp3文件就没有意义了
            InputStreamReader isr=new InputStreamReader(fis);//默认使用项目的编码.操作的时候要写文件默认的编码,这样读出来才不会乱码
            //一次读一个字符
            /*
            int c;
            while ((c=isr.readme())!=-1){
                System.out.print((char) c);
            }
             */
            //一次读一个字符数组
            char[] buffer=new char[8*1024];
            int c;
            //批量读取,放入buffer字符数组中,从第0个位置放,最多放buffer.length个
            //返回的是读到的字符个数
            while ((c=isr.read(buffer,0,buffer.length))!=-1){
                String s=new String(buffer,0,c);
                System.out.print(s);
    
            }
    
    
    
        }
    }

     4,FileReader / FileWriter

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /**
     * Created by yaming on 17-8-24.
     */
    public class ReaderWriter {
        public static void main(String[] args)throws IOException {
            /**
             * 字符流
             */
            Long time1=System.currentTimeMillis();
            FileReader fr=new FileReader("/home/yaming/Desktop/txt1");
            FileWriter fw=new FileWriter("/home/yaming/Desktop/txt2");
    
            /*char[] buffer=new char[1024];
            int c;
            while ((c=fr.readme(buffer,0,buffer.length))!=-1){
                fw.write(buffer,0,c);
                fw.flush();
            }
            //8毫秒
            */
    
            int a;
            while ((a=fr.read())!=-1){
                System.out.print(a);
                fw.write(a);
                fw.flush();
            }
            //93毫秒
    
            
            fr.close();
            fw.close();
            Long time2=System.currentTimeMillis();
            System.out.println("readme()时长:"+(time2-time1));
        }
    }

    5,字符流的过滤器

    BufferedReader  ---->readLine  一次读一行

    BufferedWriter/PrintWriter   ----->一次写一行

    package com.amazing.jdk.learn2IO_0821.stream;
    
    import java.io.*;
    
    /**
     * Created by yaming on 17-8-24.
     */
    public class BufferedReaderWriter {
        public static void main(String[] args)throws IOException {
            /**
             * 字符缓冲流
             */
            BufferedReader br=new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("/home/yaming/Desktop/test")));
            /*BufferedWriter bw=new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("/home/yaming/Desktop/test2")
                    )
            );*/
            PrintWriter pw=new PrintWriter("/home/yaming/Desktop/test2");//可以用来替换BufferedWriter,比较简单
            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();
    
        }
    
    }
  • 相关阅读:
    HDU 4536 XCOM Enemy Unknown ( 状态压缩+搜索)
    HDU 4535 吉哥系列故事——礼尚往来(水题,错排)
    HDU 4541 Ten Googol
    HDU 4544 湫湫系列故事——消灭兔子 (优先队列)
    HDU 4530 小Q系列故事——大笨钟(水题)
    HDU 4505 小Q系列故事——电梯里的爱情 (水题)
    HDU 2197 本原串 (数学)
    HDU 4540 威威猫系列故事——打地鼠 (简单DP)
    oracle数据库恢复
    编程中的命名设计那点事(转)
  • 原文地址:https://www.cnblogs.com/inspred/p/10810214.html
Copyright © 2011-2022 走看看