文章目录

  • 1. 流概述
  • 2. 输入/输出流
    • 2.1 输入流
    • 2.2 输出流
  • 3. File 类
    • 3.1 文件的创建与删除
    • 3.2 获取文件信息
  • 4. 文件输入/输出流
    • 4.1 FileInputStream 与 FileOutputStream 类
    • 4.2 FileReader 和 FIleWriter 类
  • 5. 带缓存的输入/输出流
    • 5.1 BufferedInputStream 类与 BufferedOutputStream 类
    • 5.2 BufferedReader 与 BufferedWriter 类
  • 6. 数据输入/输出流

1. 流概述

流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O(Input/Output)流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流经常与磁盘文件存取有关,但是程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口等。

2. 输入/输出流

2.1 输入流


InputStream类是字节输入流的抽象类,是所有字节输入流的父类。InputStream类的具体层次结构如图所示:

该类中所有方法遇到错误时都会引发IOException异常。下面是对该类中的一些方法的简要说明如下表所示


Java中的字符是Unicode编码,是双字节的。InputStream是用来处理字节的,在处理字符文本时不是很方便。Java为字符文本的输入提供了专门一套单独的类Reader,但Reader类并不是InputStream类的替换者,只是在处理字符串时简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类,Reader类的具体层次结构如下图所示:

2.2 输出流

OutputStream类是字节输入流的抽象类,此抽象类是表示输出字节流的所有类的超类。OutputStream类的具体层次如图所示:

OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException异常。下面对OutputStream类中的方法作一简单的介绍,如下表所示:

Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类,Writer类的层次结构如下图所示:

3. File 类


3.1 文件的创建与删除

可以使用File类创建一个文件对象,通常使用以下3种构造方法来创建文件对象。

import java.io.File;public class Demo {public static void main(String[] args) {/** 项目下的路径(默认路径): word.txt * 包中的文件路径"src/mr/word.txt * 绝对路径: C:/test/word.txt*/File f1 = new File("D:/test/word.txt");// 第一种构造方法File f2 = new File("D:/test", "word.txt");// 第二种构造方法File dir = new File("D:/test");// 文件夹File f3 = new File(dir, "word.txt");// 第三种构造方法System.out.println(f1.getAbsolutePath());// 输出文件绝对路径System.out.println(f2.getAbsolutePath());// 输出文件绝对路径System.out.println(f3.getAbsolutePath());// 输出文件绝对路径System.out.println(f1 == f2);// f1、f2只是文件的代表System.out.println(f1.equals(f2));}}

运行结果:

D:\test\word.txt
D:\test\word.txt
D:\test\word.txt
false
true

3.2 获取文件信息

File类提供了很多方法用于获取文件本身的一些信息,File类的常用方法如下表所示。

我们在D盘test文件夹中新建一个word.txt文件,然后运行以下代码:

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;public class Demo {public static void main(String[] args) {File f1 = new File("D:/test/word.txt");// 第一种构造方法System.out.println("文件是否存在:" + f1.exists());// 判断文件是否存在System.out.println("文件名:" + f1.getName());// 输出文件名System.out.println("文件绝对路径:" + f1.getAbsolutePath());// 输出文件绝对路径System.out.println("文件是否隐藏:" + f1.isHidden());// 是否为隐藏文件System.out.println("文件的字节数:" + f1.length());// 输出文件大小,单位为字节Date date = new Date(f1.lastModified());// 通过毫秒值创建日期类SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/ HH:mm:ss");System.out.println("文件最后修改时间:" + sdf.format(date));// 文件最后修改日期}}

得到结果:

文件是否存在:true
文件名:word.txt
文件绝对路径:D:\test\word.txt
文件是否隐藏:false
文件的字节数:9
文件最后修改时间:2020/12/14/ 22:37:26

然后,对文件进行删除和新建的操作:

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;public class Demo {public static void main(String[] args) {File f1 = new File("D:/test/word.txt");// 第一种构造方法boolean del = f1.delete();// 删除文件System.out.println("删除文件是否成功:" + del);try {// 已存在的文件,不能重新创建(不能覆盖已有文件)boolean create = f1.createNewFile();// 创建新的空文件System.out.println("创建文件是否成功:" + create);} catch (IOException e) {e.printStackTrace();}}}

得到结果:

删除文件是否成功:true
创建文件是否成功:true

下面是新建文件夹的例子:

import java.io.File;public class Demo {public static void main(String[] args) {File dir = new File("dir/dir1/dir2/dir3");// 只能创建1层文件夹boolean flag = dir.mkdir();// 创建文件夹boolean flag2 = dir.mkdirs();// 创建文件夹及父文件夹System.out.println("创建文件夹是否成功:"+flag);System.out.println("创建多层文件夹是否成功:"+flag2);   }}

运行结果:

创建文件夹是否成功:false
创建多层文件夹是否成功:true

删除文件夹:

import java.io.File;public class Demo {public static void main(String[] args) {File dir = new File("dir/dir1/dir2/dir3");// 只能创建1层文件夹// 删除文件路径最后一个文件夹boolean del = dir.delete();// 删除文件夹System.out.println("删除文件夹是否成功:"+del);}}

运行结果:

删除文件夹是否成功:true

查看文件夹及文件名:

import java.io.File;public class Demo {public static void main(String[] args) {File f = new File("C:/Windows/");// C盘Windows文件夹File files[] = f.listFiles();// 返回文件夹下所有子文件及子文件夹for(File tmp:files) {if(tmp.isFile()) {// 判断是否为文件System.out.println("文件:"+tmp.getName());           }else if(tmp.isDirectory()) {System.out.println("文件夹:"+tmp.getName());}}}
}

运行结果:

文件夹:addins
文件夹:appcompat
文件夹:apppatch
文件夹:AppReadiness
文件夹:assembly
文件夹:bcastdvr
文件:bfsvc.exe
文件夹:Boot
文件:bootstat.dat
文件夹:Branding
……略

4. 文件输入/输出流

程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭时,这些数据将消失。如果需要将数据永久保存,可以使用文件输入/输入流与指定的文件建立连接,将需要的数据永久保存到文件中。

4.1 FileInputStream 与 FileOutputStream 类

FileInputStream类与FileOutputStream类都是用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream类。该类继承自InputStream类。FileOutputStream类与FileInputStream类对应,提供了基本的文件写入能力。FileOutputStream类是OutoputStream类的子类。

例子:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("word.txt");FileOutputStream out = null;try {out = new FileOutputStream(f, false);// 文件输出流,为true,在文件末尾添加;为false,替换掉文件内容。String str = "你见过洛杉矶凌晨4点的样子吗?";byte b[] = str.getBytes();// 字符串转换为字节数组out.write(b);// 将字节数组中的数据写入到文件当中} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}FileInputStream in = null;try {in = new FileInputStream(f);// 输入流读文件byte b2[] = new byte[2014];// 缓冲区int len = in.read(b2);// 读入缓冲区的总字节数System.out.println("文件中的数据是:" + new String(b2, 0, len));// 可以去掉1024字节中的空格} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}}}

运行结果:

文件中的数据是:你见过洛杉矶凌晨4点的样子吗?

4.2 FileReader 和 FIleWriter 类

使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象。此时采用字符流Reader或Writer类即可避免这种现象。

FileReaderFileWriter字符流对应了FileInputStreamFileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("word.txt");FileWriter fw = null;try {fw = new FileWriter(f, false);// true为在原文件后追加新内容String str = "天行健,君子当自强不息,地势坤,君子当厚德载物";fw.write(str);// 将字符串写入文本文档} catch (IOException e) {e.printStackTrace();} finally {if (fw != null) {try {fw.close();} catch (IOException e) {e.printStackTrace();}}}FileReader fr = null;try {fr = new FileReader(f);char ch[] = new char[2014];// 缓冲区int count;// 已读出的字符数while ((count = fr.read(ch)) != -1) {// 循环读取文件中的数据直到所有字符都读完System.out.println("文件中的内容为:" + new String(ch, 0, count));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fr != null) {try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行结果:

文件中的内容为:天行健,君子当自强不息,地势坤,君子当厚德载物

5. 带缓存的输入/输出流

缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()mark()reset()方法都称为可能。

5.1 BufferedInputStream 类与 BufferedOutputStream 类

BufferedInputStream类可以对任何的InputStream类进行带缓存区的包装以达到性能的优化。
使用BufferedOutputStream输出信息和往OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。

无缓冲字节流情况下读取数据需要的时间:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("D:/Android/jdk1.8中文百度.CHM");FileInputStream in = null;long start = System.currentTimeMillis();// 数据流开始时毫秒值try {in = new FileInputStream(f);byte b[] = new byte[2014];// 缓冲区自己数组(这个缓冲区与Buffered不同)while (in.read(b) != -1) {}long end = System.currentTimeMillis();// 数据流结束时毫秒值System.out.println("运行经历的毫秒数:" + (end - start));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行结果:

运行经历的毫秒数:124

使用缓冲字节流读取数据:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("D:/Android/jdk1.8中文百度.CHM");BufferedInputStream bi = null;FileInputStream in = null;long start = System.currentTimeMillis();// 数据流开始时毫秒值try {in = new FileInputStream(f);bi = new BufferedInputStream(in);// 将文件字节流包装成缓冲流byte b[] = new byte[2014];// 缓冲区自己数组(这个缓冲区与Buffered不同)while (bi.read(b) != -1) {// 使用缓冲流读取数据}long end = System.currentTimeMillis();// 数据流结束时毫秒值System.out.println("运行经历的毫秒数:" + (end - start));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}if (bi != null) {try {bi.close();} catch (IOException e) {e.printStackTrace();}}}
}

运行结果:

运行经历的毫秒数:62

使用缓冲字节流可以大大提升效率。

同理,缓冲输出流例子:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo2 {public static void main(String[] args) {File f = new File("word.txt");FileOutputStream out = null;BufferedOutputStream bo = null;try {out = new FileOutputStream(f);bo = new BufferedOutputStream(out);// 将文件输出流包装String str = "天生我材必有用,千金散尽还复来。";byte b[] = str.getBytes();bo.write(b);// 使用缓冲字节流时,要多进行刷新操作bo.flush();// 刷新,可强制将缓冲区数据写入文件中,即使缓冲区没有写满} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}if (bo != null) {try {bo.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行生成了word.txt文档。

5.2 BufferedReader 与 BufferedWriter 类

BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入输出。

在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入至输出流中,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流中,一定要调用flush()方法。

缓冲输入流例子:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("word.txt");FileWriter fw = null;BufferedWriter bw = null;try {fw = new FileWriter(f);bw = new BufferedWriter(fw);// 将文件字符输出流包装成缓冲字符流String str1 = "世界那么大";String str2 = "我想去看看";bw.write(str1);// 第一行数据bw.newLine();// 创建一个新行bw.write(str2);// 第二行数据} catch (IOException e) {e.printStackTrace();} finally {// 要注意流的关闭顺序,先创建的后关闭if (bw != null) {try {bw.close();} catch (IOException e) {e.printStackTrace();}}if (fw != null) {try {fw.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行生成word.txt文件,显示内容:

世界那么大
我想去看看

下面是BufferedReader实例,先将word.txt中的内容修改为“会当凌绝顶 一览众山小”,分为两行写入:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("word.txt");FileReader fr = null;BufferedReader br = null;try {fr = new FileReader(f);br = new BufferedReader(fr);// 将文件字符输入流包装成缓冲字符输入流String tmp = null;// 创建临时变量int i = 1;// 计数器while ((tmp = br.readLine()) != null) {// 循环读取文件中的内容System.out.println("第" + i + "行内容:" + tmp);i++;}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (br != null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}if (fr != null) {try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行结果:

第1行内容:会当凌绝顶
第2行内容:一览众山小

6. 数据输入/输出流

数据输入输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是什么字节。

DataInputStream类只提供了一个readUTF()方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且事先也不知道这个字符串的长度,也就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以我们也只能准确地读回写入字符串。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo {public static void main(String[] args) {File f = new File("word.txt");FileOutputStream out = null;DataOutputStream dos = null;try {out = new FileOutputStream(f);dos = new DataOutputStream(out);// 将文件流包装成数据流dos.writeUTF("这是写入字符串数据");// 写入字符串数据dos.writeInt(123);// 写入整型数据dos.writeDouble(3.14);// 写入浮点型数据dos.writeBoolean(true);// 写入布尔类型数据} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (dos != null) {try {dos.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}DataInputStream di = null;FileInputStream in = null;try {in = new FileInputStream(f);di = new DataInputStream(in);System.out.println("readUTF()读取数据:" + di.readUTF());System.out.println("readInt()读取数据:" + di.readInt());System.out.println("readDouble()读取数据:" + di.readDouble());System.out.println("readBoolean()读取数据:" + di.readBoolean());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (di != null) {try {di.close();} catch (IOException e) {e.printStackTrace();}}if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}}
}

运行结果:

readUTF()读取数据:这是写入字符串数据
readInt()读取数据:123
readDouble()读取数据:3.14
readBoolean()读取数据:true

这里,因为程序写入的是字节码,如果我们不使用DataOutputStream读取数据,读出的便会是乱码。因此需要用DataOutputStream 方法将字节码解析成对应的数据类型。

JAVA核心:I/O(输入/输出)相关推荐

  1. 文件输出 java_用Java读写文件(输入/输出)-教程

    一.文件的Java I/O(输入/输出) 1.1.概述 在现代Java应用程序中,通常使用Java.nio.fileAPI来读写文件. Java将把所有输入作为字节流读取.input stream类是 ...

  2. Java I/O (输入/输出)

    Java I/O (输入/输出) I/O(输入输出)     使用输入机制,允许程序读取外部数据(包括来自磁盘.光盘等存储设备的数据).用户输入的数据     使用输出机制,允许程序记录运行状态,将程 ...

  3. java基础-基本的输入与输出

    java基础-基本的输入与输出 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.基本的输出 基本的输出,System.out 就是系统的标准输出设备,默认为显示器. 1>. ...

  4. 第15章-输入/输出 --- 理解Java的IO流

    (一)理解Java的IO流 JAVA的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出(键盘.文件.网络连接等)抽象表述为"流"( ...

  5. JAVA订单的输入输出_Java的输入/输出操作

    Java的输入\输出机制 计算机的基本功能就是通过输入输出设备与外部其他设备尽心数据的交互,从其他设备读入数据叫做输入操作,将计算机内的数据写入到其他设备叫做输出操作.可以向计算机发送数据.又可以接受 ...

  6. Java的输入/输出

    在Java中,有输入和输出,也就是IO,然后给大家介绍一下: IO(输入/输出)是比较抽象的,看不到明显的运行效果,但输入和输出是所有程序都必需的部分.使用输入机制,允许程序读取外部(包括来自磁盘.光 ...

  7. Java实现 字符串加密 输入字符串进行简单的位运算,输出加密或解密后的字符串

    Java实现 字符串加密 输入字符串进行简单的位运算,输出加密或解密后的字符串 具体代码如下: package package2;import java.util.Scanner;/*** 加密可以这 ...

  8. Java从键盘上输入与输出

    1 问题 以作业题三题为例,需要输入学生的成绩等级,然后反映出相应等级的成绩范围.直接在程序里面写出学生等级的方法不利于做出一些改变,在逻辑上也不符合常理,所以选择设置程序从键盘输入等级然后反馈出相应 ...

  9. java电话键盘字母数字转换_用Java语言将一个键盘输入的数字转化成中文输出

    用Java语言将一个键盘输入的数字转化成中文输出 将一个键盘输入的数字转化成中文输出(例如:输入:1234567 输出:一百二拾三万四千五百六拾七)用java语言实现,,请编一段... 将一个键盘输入 ...

  10. Java中I/O(输入/输出)的操作

    Java的I/O技术可以将数据保存到文本文件.二进制文件甚至是ZIP压缩文件中,以达到永久性保存数据的要求. 1.流概述 流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种.I/O(In ...

最新文章

  1. python对外发布的时间_Python如何进行时间处理
  2. linux 7个运行级别 runlevel 简介
  3. 美团技术四面经历,作者已拿到Offer!
  4. 如何更改 Linux/Unix 登录账号的密码
  5. redis的安全性及客户端工具的使用
  6. jpeg6 安装问题!
  7. 【Elasticsearch】cannot allocate because allocation is not permitted to any of the nodes
  8. python接口自动化测试(五)-其它(认证代理超时配置)
  9. jdk15不安装jre_弄懂 JRE、JDK、JVM 之间的区别与联系,你知道多少?
  10. 追忆我的2008-养成做笔记的习惯
  11. 数据库设计(有实例)
  12. Unity渲染管线,初探SRP
  13. c语言中gotoxy,关于gotoxy的问题....
  14. word文档计算机基础考试,计算机基础考试题库(含答案)48924
  15. mac 硬盘读写速度测试 软件,使用适用于Windows / Mac的最佳10工具开始测试硬盘速度...
  16. echar2 ,3 自定义右键菜单 右击事件
  17. AWS宣布计划在加拿大开设第二个区域
  18. Layer Emitter(图层发射器)
  19. 【必会系列】c语言转义字符
  20. hadoop ls命令

热门文章

  1. python移动窗口函数_设置窗口图标和移动窗口
  2. 如何让游戏里的 NPC 拥有自己的意志?
  3. C语言的从零开始和我自己的心路历程
  4. Android Studio中Cannot resolve symbol XXX的解决方法
  5. PhpSpreadsheet读取单元格内容的坑
  6. JVM中OOM和SOF的产生
  7. 上拉电阻的作用原理_电容触摸屏原理以及敦泰TP FT5X06驱动
  8. 【数据结构 严蔚敏版】 二叉树 基本操作
  9. 【概率期望】【NOIP模拟】切题
  10. grep -s 去掉 no such file or directory