36. 【Java教程】输入输出流

本小节将会介绍基本输入输出的 Java 标准类,通过本小节的学习,你将了解到什么是输入和输入什么是流;输入输出流的应用场景,File类的使用,什么是文件,Java 提供的输入输出流相关 API 等内容。

1. 什么是输入和输出(I / O)

1.1 基本概念

输入/输出这个概念,对于计算机相关专业的同学并不陌生,在计算中,输入/输出Input / Output,缩写为 I / O)是信息处理系统(例如计算机))与外界(可能是人类或其他信息处理系统)之间的通信。输入是系统接收的信号或数据,输出是从系统发送的信号或数据。

那么在 Java 中,什么是输入和输出呢?要理解这个概念,可将 Java 平台视作一个系统。Java 平台是一个孤立的系统,系统之外的所有东西都是它的环境。系统与其环境之间的交互是一种双向对话。系统要么从其环境接收消息,要么将其消息传递给环境。当系统接收到消息时,将其称为输入,与之相反的是输出。

本小节将介绍 Java 的基本输入和输出,包括从键盘读取文本输入,将文本输出到屏幕以及从文件系统读取/写入文件。

Java 提供了两个用于 I / O 的包:较旧的java.io包(不支持符号链接)和较新的java.nio(“new io”)包,它对java.nio.file的异常处理进行了改进。

1.2 简单的 Java 输出——打印内容到屏幕

一直以来,我们都在向屏幕输出内容以验证我们编写的代码逻辑。向屏幕输出内容非常简单,可以由以下两种方式来完成:

// 打印 Hello World,不换行
System.out.print("Hello World");
// 打印 Hello Java,并换行
System.out.println("Hello Java");

1.3 简单的 Java 输入——从键盘输入

java.util包下的Scanner类可用于获取用户从键盘输入的内容,我们在Java Scanner 类这一小节已经介绍过具体使用,实例如下:

import java.util.Scanner;

/**
 * @author colorful@TaleLin
 */
public class ScannerDemo {
    public static void main(String[] args) {
        // 创建扫描器对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的姓名:");
        // 可以将用户输入的内容扫描为字符串
        String name = scanner.nextLine();
        // 打印输出
        System.out.println("你好 ".concat(name).concat(" ,欢迎来到CSDN!"));
        // 关闭扫描器
        scanner.close();
    }
}

运行结果:

请输入您的姓名:
Colorful
你好 Colorful ,欢迎来到CSDN!

2. 什么是流(Stream)

Java 中最基本的输入/输入是使用流来完成的。

流是代表数据源和数据目标的对象,怎么理解这句话呢?简单来说,可以读取作为数据源的流,也可以写入作为数据目标的流。Java中的流是长度不确定的有序字节序列,它是一连串流动的字符,是以先进先出的方式发送信息的通道。

3. 输入输出流的应用场景

上面我们已经了解了输入输出流的基本概念,那么它具体是做什么用的呢?

web产品的开发中,最常开发的功能就是上传文件到服务器了,这个文件的读写过程就要用到输入输出流。对于计算机中文件的读写、复制和删除等操作也都要用到输入输出流。输入输出流可以说是无处不在,下面我们将会介绍 Java 中输入输出流相关的 API

4. File 类

在 Java 中,提供了java.io.File类对文件和目录进行操作。

File 意思为文件,文件在计算机中非常重要,我们编写的 word 文档、PPT 演示文稿、运行游戏的.exe可执行文件以及我们编写的 Java 源代码等等都是文件。

4.1 实例化

要实例化File对象,需要传入一个文件或目录的路径。

File 类提供了如下 4 个构造方法:

  1. File(File parent, String child):从父抽象路径名和子路径名字符串创建新的文件实例;
  2. File(String pathName):通过将给定的路径名字符串转换为抽象路径名,创建一个新的文件实例(最常用);
  3. File(String parent, String child):从父路径名字符串和子路径名字符串创建新的文件实例;
  4. File(URI uri):通过将给定的文件: URI转换为抽象路径名,创建一个新的文件实例。

Windows系统为例,在桌面下有一个mybj目录,该目录下有一个Hello.java文件和一个空的images目录。

我们可以单击Windows的路径栏,来获取mybj目录的绝对路径。

有了目录和文件以及路径。我们分别实例化两个File对象,实例如下:

import java.io.File;

public class FileDemo1 {
    public static void main(String[] args) {
        // 传入目录绝对路径
        File dir = new File("C:\\Users\\Colorful\\Desktop\\mybj\\images");
        // 传入文件绝对路径
        File file = new File("C:\\Users\\Colorful\\Desktop\\mybj\\Hello.java");
        // 打印两个File对象
        System.out.println(dir);
        System.out.println(file);
    }
}

我们可以直接打印File对象,File类重写了toString()方法,查看 Java 源码,toString()方法直接返回了getPath()实例方法,此方法返回构造方法传入的路径字符串:

运行结果:

C:\Users\Colorful\Desktop\mybj\images
C:\Users\Colorful\Desktop\mybj\Hello.java

上面代码中,使用\\表示Windows下的路径分隔符\LinuxMacOS下使用正斜杠/作为路径分隔符。假设是同样的目录结构,在MacOSLinux下是这样表示的:

File dir = new File("/Users/Colorful/Desktop/mybj/images");

因为Windows平台和其他平台路径分隔符不同,使用不同平台的开发者就难以保证路径分隔符的统一。

为了保证代码更好的兼容性,File类下提供了一个静态变量separator,用于表示当前平台的系统分隔符:

// 根据当前平台输出 / 获取 \
System.out.println(File.separator);

4.2 绝对路径和相对路径

在实例化File对象时,既可以传入绝对路径,也可以传入相对路径。

绝对路径是以根目录开头的完整的全路径,上面代码实例中传入的是绝对路径,我们再来看看什么是相对路径,以及如何传入相对路径。

相对路径指的是当前文件所在的路径引起的跟其它文件(或文件夹)的路径关系。听起来有点绕,我们举例来说明一下,在mybj目录下新建一个FileDemo2.java文件,此时mybj目录的文件目录树结构如下:

└── mybj
    ├── FileDemo2.java
    ├── Hello.java
    └── images

内容如下:

import java.io.File;
import java.io.IOException;

public class FileDemo2 {
    public static void main(String[] args) throws IOException {
        // 传入目录相对路径
        File dir = new File(".\\images");
        File mybjDir = new File("..\\mybj");
        // 传入文件相对路径
        File file = new File(".\\Hello.java");
    }
}

上面代码的File构造方法中传入的就是相对路径,代码中的.表示当前目录,..表示上级目录。

Tips: 我们在实例化 File 对象时,不会产生对磁盘的操作,因此即使传入的文件或目录不存在,代码也不会抛出异常。只有当调用 File 对象下的一些方法时,才会对磁盘进行操作。

File 对象下有 3 个表示路径的实例方法:

  1. String getPath():将抽象路径名转换为路径名字符串;
  2. String getAbsolute():返回此抽象路径名的绝对路径名字符串;
  3. String getCanonicalPath():返回此抽象路径名的规范路径名字符串。

我们可以调用这 3 个方法并打印结果,实例如下:

import java.io.File;
import java.io.IOException;

public class FileDemo2 {
    public static void main(String[] args) throws IOException {
        // 传入目录相对路径
        File imagesDir = new File(".\\images");
        File mybjDir = new File("..\\mybj");
        // 传入文件相对路径
        File file = new File(".\\Hello.java");
        
        System.out.println("-- imagesDir ---");
        System.out.println(imagesDir.getPath());
        System.out.println(imagesDir.getAbsolutePath());
        System.out.println(imagesDir.getCanonicalPath());

        System.out.println("-- mybjDir ---");
        System.out.println(mybjDir.getPath());
        System.out.println(mybjDir.getAbsolutePath());
        System.out.println(mybjDir.getCanonicalPath());

        System.out.println("-- file ---");
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }
}

运行结果:

-- imagesDir ---
.\images
C:\Users\Colorful\Desktop\mybj\.\images
C:\Users\Colorful\Desktop\mybj\images
-- mybjDir ---
..\mybj
C:\Users\Colorful\Desktop\mybj\..\mybj
C:\Users\Colorful\Desktop\mybj
-- file ---
.\Hello.java
C:\Users\Colorful\Desktop\mybj\.\Hello.java
C:\Users\Colorful\Desktop\mybj\Hello.java

通过运行结果可以看出,规范路径名就是把...转换为标准的绝对路径。

4.3 判断对象是文件还是目录

我们可以通过如下两个方法判断 File 对象是文件还是目录:

  1. boolean isFile():测试此抽象路径名表示的文件是否为普通文件;
  2. boolean isDirectory():测试此抽象路径名表示的文件是否为目录。

实例如下:

import java.io.File;

public class FileDemo3 {

    public static void printResult(File file) {
        // 调用isFile()方法并接收布尔类型结果
        boolean isFile = file.isFile();
        String result1 = isFile ? "是已存在文件" : "不是已存在文件";
        // 掉用isDirectory()方法并接收布尔类型而己过
        boolean directory = file.isDirectory();
        String result2 = directory ? "是已存在目录" : "不是已存在目录";
        // 打印该file对象是否是已存在文件/目录的字符串结果
        System.out.print(file);
        System.out.print('\t' + result1 + '\t');
        System.out.println(result2);
    }

    public static void main(String[] args) {
        // 传入目录绝对路径
        File dir = new File("C:\\Users\\Colorful\\Desktop\\mybj\\images");
        // 传入文件绝对路径
        File file = new File("C:\\Users\\Colorful\\Desktop\\mybj\\test.java");
        FileDemo3.printResult(dir);
        FileDemo3.printResult(file);
    }
}

运行结果:

C:\Users\Colorful\Desktop\mybj\images	不是已存在文件	是已存在目录
C:\Users\Colorful\Desktop\mybj\test.java	不是已存在文件	不是已存在目录

代码中我们封装了一个静态方法printResult(),此方法打印 File 对象是否是文件/目录。值得注意的是,我们的磁盘中不存在C:\Users\Colorful\Desktop\mybj\test.java,因此无论调用isFile()方法还是isDirectory()方法,其返回结果都为false

4.4 创建和删除目录

4.4.1 创建目录

对于一个不存在的目录,我们可以使用boolean mkdir()方法创建一个目录。例如,我们想在mybj目录下创建一个codes目录,就可以使用该方法编写一段创建目录的代码。

实例如下:

import java.io.File;

public class FileDemo4 {

    public static void main(String[] args) {
        // 传入目录绝对路径
        File dir = new File("C:\\Users\\Colorful\\Desktop\\mybj\\codes");
        if (!dir.exists()) {
            // 调用 mkdir() 方法
            boolean result = dir.mkdir();
            if (result) {
                System.out.println("目录创建成功");
            }
        }
    }
}

代码中我们调用了File对象的boolean exists()方法,此方法用于测试由此抽象路径名表示的文件或目录是否存在。当不存在时,我们才去创建目录。

运行代码前,mybj文件目录树结构如下:

└── mybj
    ├── FileDemo2.java
    ├── Hello.java
    └── images

运行结果:

目录创建成功

运行代码后,mybj目录下多了一个codes目录,树结构如下:

└── mybj
    ├── FileDemo2.java
    ├── Hello.java
    ├── images
    └── codes

另外,File 类也提供了一个boolean mkdirs()方法,用来创建由这个抽象路径名命名的目录,包括任何必要但不存在的父目录。实际上是在递归执行mkdir()方法。

4.4.2 删除目录

如果我们想要删除刚刚创建的codes目录,可以调用boolean delete()方法,实例如下:

import java.io.File;

public class FileDemo5 {
    public static void main(String[] args) {
        // 传入目录绝对路径
        File dir = new File("C:\\Users\\Colorful\\Desktop\\mybj\\codes");
        if (dir.exists()) {
            // 调用 delete() 方法
            boolean deleted = dir.delete();
            if (deleted) {
                System.out.println("删除目录成功");
            }
        }
    }
}

运行代码前,mybj文件目录树结构如下:

└── mybj
    ├── FileDemo2.java
    ├── Hello.java
    ├── images
    └── codes

运行结果:

删除目录成功

运行代码后,树结构如下:

└── mybj
    ├── FileDemo2.java
    ├── Hello.java
    └── images

4.5 创建和删除文件

对于文件类型的File对象,可以通过boolean createNewFile()方法创建一个新文件,使用boolean delete()方法删除文件。其调用方法和创建/删除目录相同,此处不再赘述。

关于更多File对象的操作,可翻阅官方文档。

5. InputStream 抽象类

5.1 概述

java.io.InputStream抽象类是 Java 提供的最基本的输入流,它是所有输入流的父类。其最常用的抽象方法int read()签名如下:

public abstract int read() throws IOException;

这个方法用于读取输入流的下一个字节,返回的int如果为-1,则表示已经读取到文件末尾。

InputStream与其子类的 UML 图如下所示:

5.2 FileInputStream 实现类

我们将以最常用的FileInputStream实现类为例进行学习。其他实现类大同小异,如有需要可翻阅官方文档。

FileInputStream就是从文件流中读取数据,我们在mybj目录下新建一个文本文档Hello.txt,并输入如下内容:

Hello mybj!

读取Hello.txt文件中数据的实例代码如下:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamDemo1 {

    public static void main(String[] args) throws IOException {
        // 实例化文件流
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Colorful\\Desktop\\mybj\\Hello.txt");
        for (;;) {
            int n = fileInputStream.read();
            if (n == -1) {
                // read() 方法返回-1 则跳出循环
                break;
            }
            // 将n强制转换为 char 类型
            System.out.print((char) n);
        }
        // 关闭文件流
        fileInputStream.close();
    }
}

运行结果:

Hello mybj!

如果我们打开了一个文件并进行操作,不要忘记使用close()方法来及时关闭。这样可以让系统释放资源。

6. OutputStream 抽象类

6.1 概述

OutPutStream抽象类是与InputStream对应的最基本的输出流,它是所有输出流的父类。其最常用的抽象方法void write(int b)签名如下:

public abstract void write(int b) throws IOException;

这个方法用于写入一个字节到输出流。

OutputStream与其子类的 UML 图如下所示:

6.2 FileOutputStream 实现类

我们同样以最常用的FileOutputStream实现类为例进行学习。其他实现类大同小异,如有需要可翻阅官方文档。

FileOutputStream就是向文件流中写入数据,下面我们向mybj目录下的文本文档Hello.txt输入一段字符串HHH。完整实例如下:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Colorful\\Desktop\\mybj\\Hello.txt");
        // 写入 3 个H字符
        fileOutputStream.write(72);
        fileOutputStream.write(72);
        fileOutputStream.write(72);
        fileOutputStream.close();
    }
}

运行代码后,Hello.txt后面成功写入了 3 个字符H

7. 小结

通过本小节的学习,我们知道了什么是输入输出流的概念,输入输出流经常用于上传文件到服务器的场景。想要通过 Java 操作文件和目录,要学会使用java.io.File类,InputStreamOutputStream分别是所有输入流和所有输出流的父类,FileInputStream实现了文件流的输入,FileOutputStream实现了文件流的输出。还有很多其它实现类我们没有介绍到,但使用方法大同小异,希望同学可以在用到时自行查阅文档来学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/678433.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【翻译软件】CopyTranslator复制即翻译的外文辅助阅读翻译软件NO.102

使用平台:Windows/Linux/macOS 设置里选择翻译引擎和翻译API,谷歌翻译已经退出中国了,但还是提供了镜像地址 一、复制即翻译 只需要复制文本到剪贴板,就可以查看翻译结果 记得开启“自动粘贴”哦。 二、多段同时翻译 三、智能…

别再emo了,还不赶紧去考PMP,搞钱要紧~

自从疫情之后经济大不如从前,现在大环境都不好,很多公司都在裁员,像我朋友就在上个月被裁掉了,虽说拿了补偿但也不可能靠那点补偿生活的,所以我朋友找了很久的工作,但是由于大环境的缺失所以导致他的薪资直…

误删照片怎么办?恢复删除的图片,3个指南!

在我们的日常生活中,照片就像是我们的小秘密宝藏,记录着我们与亲朋好友一起嗨皮的时光,还有那些让我们激动不已的人生大事。可是,有时候我们可能会因为一时的疏忽,比如手滑点错了按钮,或者在清理手机内存时…

微软云计算Windows Azure(一)

目录 一、微软云计算平台二、微软云操作系统Windows Azure(一)Windows Azure概述(二)Windows Azure计算服务(三)Windows Azure存储服务(四)Windows Azure Connect(五&…

2003远程桌面端口修改,修改远程桌面端口的操作

在信息技术领域,远程桌面端口的修改是一项至关重要的安全操作,尤其在运行Windows 2003操作系统的环境中。对于系统管理员而言,了解和掌握如何正确、有效地修改远程桌面端口,是确保服务器安全、防止潜在攻击的关键步骤。 首先&…

图解Mysql索引原理

概述 是什么 索引像是一本书的目录列表,能根据目录快速的找到具体的书本内容,也就是加快了数据库的查询速度索引本质是一个数据结构索引是在存储引擎层,而不是服务器层实现的,所以,并没有统一的索引标准,…

笔记:如何在pycharm中使用anaconda的虚拟环境,新建工程和更改现有工程的虚拟环境。

1.用anaconda创建虚拟环境 (base) C:\Users\Administrator>conda -V conda 24.5.0(base) C:\Users\Administrator>conda create -n appenv python Channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- defaults Platform: win-64 Collecting package m…

upload-labs-第一关和第二关

目录 第一关 思路: 1、上传一个php文件 2、查看源码 3、查看文件上传地址 4、BP抓包,修改文件后缀名 5、使用蚁剑连接 第二关 1、这一关也可以跟第一关一样的方法进行绕过 2、上传一个一句话木马文件 第一关 原理: 思路&#xff1a…

Vray渲染器的作用是什么?渲染100邀请码1a12

Vray是一款专业的渲染器,为不同领域的CG制作者提供高质量的渲染,它有以下几个作用。 1、Vray能创建专业的照明效果,渲染最逼真的画面,让场景生动无比。 2、Vray能模拟各种自然光和人造光源,如太阳光、天空光、区域光…

乡村振兴的乡村生态文明建设:加强乡村生态环境保护,推进乡村绿色发展,打造生态宜居的美丽乡村

目录 一、引言 二、乡村生态环境保护的必要性 三、加强乡村生态环境保护的措施 (一)完善法律法规,强化制度保障 (二)加强宣传教育,提高环保意识 (三)推广生态农业,…

机器视觉检测--相机

一,相机就是CCD么? 通常,我们把相机都叫作CCD,CCD已经成了相机的代名词。其实很可能正在使用的是CMOS。CCD以及CMOS都称为感光元件,都是将光学图像转换为电子信号的半导体元件。他们在检测光时都采用光电二极管&#…

5252DE 5G 外场通信测试仪

5252DE 5G 外场通信测试仪 集先进算法和高性能硬件于一体的便携式测试仪表 产品综述 5252DE 5G 外场通信测试仪是集合高性能频谱处理模块、多制式解析算法软件于一体的手持式测试仪表,具有很好的便携性、兼容性与可拓展性。 5252DE 具有工作频段宽、性能指标高…

ICLR24大模型提示(2/11) | BatchPrompt:多样本批量提示事半功倍

【摘要】由于大型语言模型 (LLM) 的 token 限制不断增加,使得长上下文成为输入,使用单个数据样本进行提示可能不再是一种有效的方式。提高效率的一个直接策略是在 token 限制内对数据进行批处理(例如,gpt-3.5-turbo 为 8k&#xf…

深度学习Week15——利用TensorFlow实现猫狗识别2

文章目录 深度学习Week15——利用TensorFlow实现猫狗识别2—数据增强 一、前言 二、我的环境 三、前期工作 1、配置环境 2、导入数据 四、数据预处理 1、加载数据 2、可视化数据 3、检查数据 4、配置数据集 五、构建VGG-16模型 1、设置动态学习率 2、早停与保存最佳模型参数 五…

1-力扣高频 SQL 50 题(基础版)

1.可回收且低脂的产品(基础版) -- 条件 既是低脂又是可回收 where low_fats"Y" AND recyclable"Y" -- 查询属性 产品编号 select product_id select product_id from Products where low_fats"Y" AND recyclable"…

MicroPython教程:ESP8266 快速参考

ESP8266 快速参考 Adafruit Feather HUZZAH 板(图片来源:Adafruit)。 以下是基于 ESP8266 的开发板的快速参考。如果这是您第一次使用该板,请考虑先阅读以下部分: 关于 ESP8266 端口的一般信息ESP8266 的 MicroPytho…

Unity Obi Rope失效

文章目录 前言一、WebGL端Obi Rope失效二、Obi Rope 固定不牢三、使用Obi后卡顿总结 前言 Obi 是一款基于粒子的高级物理引擎,可模拟各种可变形材料的行为。 使用 Obi Rope,你可以在几秒内创建绳索和杆子,同时完全控制它们的形状和行为&…

【DMG80480T070_05WTR】文本显示、数据变量显示、基本图形显示、实时曲线功能及串口下载流程(串口屏)

这篇文章写给自己看的,要不然明天就忘完了。 首先新建一个工程,名称路径自拟。 导入一张图片,名字从00开始,图片放到本工程的DWIN_SET下面就行,后面如果没有特殊说明,生成的配置或者放入的图片全都放在该文…

常见排序算法之归并排序

目录 一、什么是归并排序 二、递归实现 2.1 思路 2.2 C语言源码 三、非递归实现 3.1 思路 3.2 C语言源码 一、什么是归并排序 归并排序是一种基于分治思想的排序算法。它的基本思想是将原始的待排序序列不断地分割成更小的子序列,直到每个子序列中只有一个元…

白酒:不同产地白酒的口感差异与品鉴技巧

云仓酒庄豪迈白酒作为中国白酒的品牌之一,其口感和品质深受消费者喜爱。然而,不同产地的白酒在口感上存在一定的差异,了解这些差异以及掌握正确的品鉴技巧,对于更好地品味云仓酒庄豪迈白酒以及其他不同产地的白酒至关重要。 首先&…