Java IO流常用类的使用方法

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();
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容