Java IO 基础

一、File 类

java.io.File 类:文件和目录路径名的抽象表示形式。
通过File对象可以访问文件的属性、访问空文件或目录。

分隔符:

路径分割符:File.pathSeparator
名称分割符:File.separator

路径的表示方式:

path = "E:\test\2.jpg";
path = "E:" + File.separator + "test" + File.separator + "2.jpg";
path = "E:/test/2.jpg";
第二种可以跨平台,推荐第三种

相对路径和绝对路径构造File对象:

相对路径
File file = new File(parentPath,name);
File file = new FIle(new File(parentPath),name);
System.out.println(file.getName);
System.out.println(file.getPath);

绝对路径
File file = new FIle(E:/02.jpg);
注意:没有盘符时,以 user.dir 构建

File的相关方法:

1. 文件名

getName() 文件名、路径名
getPath() 路径名
getAbsoluteFile() 绝对路径锁对应的File对象
getAbsolutePath() 绝对路径名
getParent() 父目录,相对路径的父目录,可能为null
renameTo(File newName) 重命名

2. 判断信息

exists()
canWrite()
canReader()
isFile()
isDirectory() 是否是文件夹(不是真实存在的默认为文件夹)
isAbsolute() 是否为绝对路径。消除平台差异,ie以盘符开头,其他的以/开头

3. 长度

length():返回字节数。

4. 创建、删除

createNewFil() 不存在创建新文件
delete() 删除文件
static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
static createTempFile(前缀3个字节长,后缀默认.temp,目录)
deleteOnExit() 退出虚拟机时删除,常用于删除临时文件

5. 操作目录

mkdir() 必须确保父目录存在,不存在则创建失败
mkdirs() 如果目录链不存在,一同创建
list() 文件|目录的名称
listFiles() 文件|目录的Flile对象
static listRoots() 根路径

示例
public static void main(String[] args) throws IOException {
  String path = "C:/User/zcq12/";
  File file = new File(path);
  // file.mkdirs();
  if (file.isDirectory()) { // 存在并且为目录
   System.out.println("=============子目录||文件的名称=============");
   String[] subNames = file.list();
   // 遍历出目标文件夹下的文件以及文件夹
   for (String temp : subNames) {
    System.out.println(temp);
   }
   System.out.println("=============子目录||文件的File对象==========");
   File[] subFiles = file.listFiles();
   for (File temp : subFiles) {
    System.out.println(temp.getAbsolutePath());
   }
   System.out.println("=============子文件.java对象=================");
   // 命令设计模式
   subFiles = file.listFiles(new FilenameFilter() {
    // dir:代表src
    @Override
    public boolean accept(File dir, String name) {
     // System.out.println(dir.getName());
     // 遍历dir文件夹下所有的以 .java结尾 并且 不是文件夹的 .java结尾文件
     return name.endsWith(".java") && !(new File(dir, name).isDirectory());
    }
   });
   for (File temp : subFiles) {
    System.out.println(temp.getAbsolutePath());
   }
  }
  System.out.println("============递归输出 孙级目录|文件的绝对路径名称=============");
  getAllFiles();
 }

 /**
  * 输出子孙级目录|文件的绝对路径名称 1. listFiles() 2. 递归  可以做文件搜索
  */
 public static void getAllFiles() {
  String path = "C:/User";
  File parent = new File(path);
  printName(parent);
 }

 private static void printName(File file) {
  if (file == null || !file.exists()) {
   return;
  }
  System.out.println(file.getAbsolutePath());
  if (file.isDirectory()) {
   for (File sub : file.listFiles()) {
    printName(sub);
   }
  }
 }

IO 流

一、流的概念

流:流动流向。从一段到另一端,源头与目的地。

程序 与 文件|数组|网络连接|数据库。以程序为中心(即输出还是输出都是相对于程序来说的)。

二、IO 流分类

  • 1、流向:
    • 输入流
    • 输出流
  • 2、数据:
    • 节流:二进制,可以是一切文件,包括纯文本、doc、音频、视频、图片
    • 字符流:纯文本文件
  • 3、功能
    • 节点流:包裹源头
    • 处理流:增强功能,提供性能

三、字节流与字符流(重点)与文件

1、字节流

  • 输入流
    • inputStream
      • read(byte[] b)
      • read(byte[] b, int off, int len)
      • close()
    • 实现类:FIleInputStream()
  • 输出流
    • outPutStream
      • write(byte[] b)
      • wirte(byte[] b, int off, int len)
      • flush()
      • close()
    • 实现类:FileOutputStream()

2、字符流

  • 输入流
    • reader
      • read(char[] cbuf)
      • read(char[] cbuf, int off, int len)
      • close()
    • 实现类:FileReader()
  • 输出流
    • writer
      • write(char[] cbuf)
      • write(char[] cbuf, int off, int len)
      • flush()
      • close()
    • 实现类:FileWritre()

四、操作

1、举例 ---> 读取文件

(1)关联房子 ---> 建立与文件联系

(2)选择搬家公司 ---> 选择对应的流

(3)搬家 ---> 读取|写出

  1. 卡车大小 ---> 数组大小

  2. 运输 ---> 读取、写出

(4)打发走over ---> 释放资源

2、操作

  1. 建立联系
  2. 选择流
  3. 操作
    1. 数组大小
    2. read、write
  4. 释放资源

实例代码

1. 字节流

输入文件

public class Demo03_inputStream {
    public static void main(String[] args) {
        // 1. 建立联系
        File file = new File("D:/test/a.txt");
        // 2. 选择流
        InputStream is = null;
        try {
            is = new FileInputStream(file);
            byte[] car = new byte[1024];
            int len = 0; // 接收实际读取大小
            // 循环读取
            try {
                // 3. 操作
                while (-1 != (len = is.read(car))) {
                    // 输出 字节数组转化成字符串
                    String info = new String(car, 0, len);
                    System.out.println(info);
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("读取文件失败");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在");
        } finally {
            if (null != is) {
                try {
                    // 4. 释放资源
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭输入流失败");
                }}}}}

写出文件

public class Demo04_outputStream {
    public static void main(String[] args) {
        // 1. 建立联系
        File file = new File("D:/test/a.txt");
        // 2. 选择流
        OutputStream os = null;
        try {
            // 为true时,以追加形式写出文件;为false时,覆盖
            os = new FileOutputStream(file, true);
            String str = "this is a str \r\n";
            // 字符串转字节数组
            byte[] data = str.getBytes();
            os.write(data, 0, data.length);
            os.flush(); // 强制刷新数据
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件没有找到");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件写出失败");
        } finally {
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭输出流失败");
                }}}}}

文件拷贝

public  void copyFile(File src, File dest) throws IOException {
        if (!src.isFile()) {
            System.out.println("只能copy文件");
            throw new IOException("只能copy文件");
        }

        if (dest.isDirectory()) {
            System.out.println("不能建立与文件夹同名的文件");
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件");
        }

        InputStream is = null;
        OutputStream os = null;
        byte[] data = new byte[1024];
        int len = 0;
        is = new FileInputStream(src);
        os = new FileOutputStream(dest);
        while (-1 != (len = is.read(data))) {
            os.write(data, 0, len);
        }
        os.flush();
        // 先开的后关闭
        os.close();
        is.close();
    }

文件夹的拷贝

/**
     * 文件夹的copy 1、文件:复制 copyFile 2、文件夹:创建 mkdirs() 3、递归查找子孙级
     */
    public static void copyDir(String srcPath, String destPath) {
        File src = new File(srcPath);
        File dest = new File(destPath);
        if (src.isDirectory()) {
            dest = new File(destPath, src.getName());
        }
        copyDieDetails(src, dest);
    }

    private static void copyDieDetails(File src, File dest) {
        if (src.isFile()) {
            try {
                copyFile(src, dest);// 调用上面文件拷贝的方法
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (src.isDirectory()) {
            dest.mkdirs();
            for (File sub : src.listFiles()) {
                copyDieDetails(sub, new File(dest, sub.getName()));
            }
        }
    }

2. 字符流

只能处理纯文本,全部为可见字符。.txt.html
对应的节点流:

  • Reader --> FileReader
  • Writer --> FileWriter

使用方式和字节流相似:

  • 建立联系
  • 选择流: FileReadre、FileWriter
  • 读取 char[] flush = new char[1024]
  • 关闭

3. 处理流

  • 缓冲流
    • 字节缓冲流
      • BufferedInputStream
      • BufferedOutputStream
    • 字符缓冲流
      • BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
      • BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
        • readLine() 读取一个文本行。
      • BufferedWriter(Writer out)
      • BufferedWriter(Writer out, int sz)
        • newLine() 写入一个行分隔符

字符缓冲流 实现文件拷贝

public class Demo07_bufferedChar {
    public static void main(String[] args) {
        File src = new File("D:/test/a.txt");
        File dest = new File("D:/test/b.txt");

        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            reader = new BufferedReader(new FileReader(src));
            writer = new BufferedWriter(new FileWriter(dest));
            // 旧的读取方法
            /*
             * char[] flush = new char[1024]; int len = 0;
             * while(-1!=(reader.read(flush))){ writer.write(flush, 0, len); }
             */

            // 新增方法的操作
            String line = null;
            while (null != (line = (reader.readLine()))) {
                writer.write(line);
                // writer.append("\r\n");
                writer.newLine();// 换行符号
            }
            writer.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
}}}

4. 转换流

字节流转为字符流,设计处理乱码问题。

  1. 编码与解码概念
    1. 编码: 字符 ---编码字符集-->二进制
    2. 解码: 二进制 ---解码字符集-->字符
  2. 乱码
    1. 编码与解码的字符集不统一
    2. 字节缺少,长度丢失

转换流

  • 输入流 InputStreamReader (解码)
  • 输出流 OutputStreamWriter (编码)

5. 其他流

字节流

  • 字节数组 节点流
    • 输入流: ByteArrayInputStream read(byte[] b, int off, int len) + close();(close可用可不用
    • 输出流: ByteArrayOutputStream write(byte[] b, int off, int len) + toByteArray() (不要使用多态)

处理流

  • 数据类型处理流(基本类型+String)
    • 输入流:DataInputStream readXxx
      • read(byte[] b)
      • read(byte[] b, int off, int len)
      • readBoolean()
      • readByte()
      • readByte()
      • readDouble()
      • readFloat()
      • readFully
    • 输出流:DataOutputstream WriteXxx
      • 。。。同上
  • 引用类型(对象) 保留数据+类型
    • 反序列化 ObjectOutputStream readObject()
    • 序列化 ObjectInputStream wirteObject()
    • 注意:
      • 先序列化后反序列化。反序列化顺序必须和序列化顺序一致
      • 不是所有的对象都可以序列化,必须实现java.io.Serilizable接口。
      • 不是所有的属性都序列化,不需要序列化的属性用transient

注意:

  • java.io.EOFException:没有读取到相关的内容
  • 读取顺序可能存在数据问题

ByteArrayInputstream 和 ByteArrayOutputStream

public static void main(String[] args) throws IOException {
        byte[] data = getBytesFromFile("D:/test/a.txt");
        toFileFromByteArray(data, "D:/test/c.txt");
    }

    /**
     * 文件 --> 程序--> 字节数组
     * 
     * @throws IOException
     */
    public static byte[] getBytesFromFile(String path) throws IOException {
        File file = new File(path);
        byte[] dest = null;
        InputStream is = new BufferedInputStream(new FileInputStream(file));
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] flush = new byte[1024];
        int len = 0;
        while (-1 != (len = is.read(flush))) {
            bos.write(flush, 0, len);
        }
        bos.flush();
        dest = bos.toByteArray();
        // 先开后关
        bos.close();
        is.close();
        return dest;
    }

    /**
     * 字节数组 --> 程序 --> 文件
     * 
     * @throws IOException
     */
    public static void toFileFromByteArray(byte[] src, String dest) throws IOException {
        File file = new File(dest);
        InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
        byte[] flush = new byte[1024];
        int len = 0;
        while (-1 != (len = is.read(flush))) {
            os.write(flush, 0, len);
        }
        os.flush();
        os.close();
        is.close();
    }

对象通过流实现序列化和反序列化

Object:

/**
 * 空接口只是一个标识,说明可以序列化
 * 不需要序列化的属性加  transient
 */
public class Employee implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
    private transient String name;
    private double salary;
    ...

ObjectInputStream 和 ObjectOutputStream

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        seri("D:/test/seri.txt");
        read("D:/test/seri.txt");
    }

    // 序列化
    public static void seri(String destPath) throws FileNotFoundException, IOException {
        Employee emp = new Employee("张三", 5000);
        int[] arr = { 1, 2, 3, 54 };
        File dest = new File(destPath);
        ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
        oos.writeObject(emp);
        oos.writeObject(arr);
        oos.flush();
        oos.close();
    }

    // 反序列化
    public static void read(String destPath) throws FileNotFoundException, IOException, ClassNotFoundException {
        File dest = new File(destPath);
        ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(dest)));
        Object obj = ois.readObject();
        if (obj instanceof Employee) {
            Employee emp = (Employee) obj;
            System.out.println(emp.getName());
            System.out.println(emp.getSalary());
        }
        int[] arr = (int[]) ois.readObject();
        System.out.println(Arrays.toString(arr));
        ois.close();
    }

6. 关闭流方法

public class Demo11_FileUtil {
    /**
     * 关闭流 可变参数 ...: 代表参数随意指定。只能放在形参的最后一个位置,处理方式与数组一致
     * 使用:Demo11_FileUtil.close(is, os, oos)
     */
    public static void close(Closeable... io) {
        for (Closeable temp : io) {
            if (null != temp) {
                try {
                    temp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }}}}

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

推荐阅读更多精彩内容

  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序运行的过程中,可能需要对一些设备进...
    征程_Journey阅读 948评论 0 1
  • # 3.1 File # ## 3.1.1 File基本概念 ## 1.基本概念 -File类用于表示文件(目录)...
    闫子扬阅读 455评论 0 0
  • 在经过一次没有准备的面试后,发现自己虽然写了两年的android代码,基础知识却忘的差不多了。这是程序员的大忌,没...
    猿来如痴阅读 2,829评论 3 10
  • 英子夜半三更的发了一个微圈,那个谁谁谁打我,还扬言说杀了我。 冷不丁一看,吓我一跳,立马拨电话过去,问她什么情况!...
    猫咪鱼阅读 397评论 2 1
  • 1.工作上完成外卡报表 2.发现频道分析跟班彪合稿 3.熟悉简书流程
    陈一杰_阿甘歪传阅读 167评论 0 0