「解析文件流,Java之FileOutputStream助您轻松操作文件!」
🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8
咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java之IO流啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~
前言
Java是一门广泛应用于开发各种应用程序的编程语言,也广泛应用于文件操作方面,其中FileOutputStream
是Java IO包中常用的类之一。本文将介绍如何使用FileOutputStream
类来操作文件流,以方便开发人员更加轻松地读写文件。
摘要
本文主要介绍了Java中文件操作的基本知识和FileOutputStream
类的使用方法。在介绍FileOutputStream
类之前,我们先了解了Java IO包中的一些基本的类,比如InputStream、OutputStream、File、FileReader
等等。在具体的介绍中,我们详细讲解了如何使用FileOutputStream来写入文件,并给出了相应的示例代码。最后,我们还介绍了一些FileOutputStream
类的常用方法。
FileOutputStream
1. Java IO包基础
Java IO包是Java编程语言中用于读写数据的API。它提供了一个非常简单和易于使用的接口,以帮助我们轻松地读写文件。在Java IO包中,常用的类有InputStream
、OutputStream
、Reader
和Writer
,它们都是抽象类。另外,Java IO包中还包含了一些具体的类,如File、FileInputStream、FileOutputStream
等。
2. FileOutputStream类介绍
FileOutputStream
类是Java IO
包中用于写入文件的类。通过FileOutputStream
类,我们可以将数据写入到文件中。
2.1 创建FileOutputStream对象
FileOutputStream fos = new FileOutputStream("example.txt");
2.2 写入数据
String data = "Hello, world!";
byte[] bytes = data.getBytes();
fos.write(bytes);
2.3 关闭FileOutputStream
写入完成后,需要关闭FileOutputStream
,以释放资源。
fos.close();
3. 常用方法
常用的方法有:
write(byte[] b)
: 将字节数组写入数据流。write(byte[] b, int off, int len)
: 将字节数组中的一部分写入数据流。flush()
: 刷新数据流。close()
: 关闭输出流。
应用场景
FileOutputStream
是Java IO库中的一个类,它用于写入二进制数据到文件中。以下是FileOutputStream
的应用场景分析:
- 文件写入:
FileOutputStream
被广泛用于将数据写入文件,特别是在需要将二进制数据写入文件中时。 - 网络传输:
FileOutputStream
也可以用来将二进制数据写入网络流中传输,一些常见的网络编程框架使用FileOutputStream
来实现数据的写入。 - 数据库存储:将二进制数据写入数据库中也是
FileOutputStream
的应用之一。
优缺点分析
优点:
- 速度快:
FileOutputStream
是Java IO库中最快的输出流之一,因为它不会像BufferedOutputStream
一样缓存数据,直接写入。 - 支持二进制数据:
FileOutputStream
可以写入任何类型的数据,包括二进制数据。 - 灵活性高:
FileOutputStream
可以通过多种方式进行数据写入,例如:按字节写入、按字符写入等。
缺点:
- 不支持缓存:
FileOutputStream
不支持数据缓存,这意味着每次写入操作都需要打开文件并写入数据,增加了文件I/O的开销。 - 不能在文件中追加数据:
FileOutputStream
只会覆盖文件中原有的数据,不能在文件最后面追加数据。 - 不支持高级的字符处理:
FileOutputStream
只能处理字节数据而不能处理字符数据,必须通过其他类如OutputStreamWriter
进行处理。
综上所述,FileOutputStream
是Java IO库中功能强大的输出流之一,可用于高效地将二进制数据写入文件、网络流或数据库中。但是,它不支持缓存和追加数据等高级功能。因此,在选择输出流时要权衡其优势和劣势。
4. 示例代码
下面是一个示例代码,展示了如何使用FileOutputStream将数据写入文件中。
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriterExample {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("example.txt");
String data = "Hello, world!";
byte[] bytes = data.getBytes();
fos.write(bytes);
fos.close();
}
}
测试运行结果如下:
5. 测试用例
5.1 用例代码
我们可以编写一些测试用例来确保代码的正确性。下面是一个简单的测试用例,展示了如何验证代码是否按预期工作。
package com.example.javase.io.fileOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @Author bug菌
* @Date 2023-10-15 19:40
*/
public class FileOutputStreamTest {
public static void main(String[] args) throws IOException {
String data = "Hello, world,jym!";
File file = new File("./template/hello.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getBytes());
fos.close();
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
fis.read(buffer);
String result = new String(buffer).trim();
fis.close();
if (data.equals(result)) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
}
}
5.2 代码解析
该代码演示了如何使用Java的FileOutputStream
类来写文件以及使用FileInputStream
类来读文件。首先创建了一个字符串数据,然后使用FileOutputStream
将其写入到文件中。写入完成后,使用FileInputStream
读取文件中的内容,并将读取结果与原始数据进行比较,以确认写入和读取都成功。最后,根据比较结果输出相应的信息(Pass 或 Fail)。
5.3 测试结果
如上测试用例测试结果如下:
6. 源码分析
FileOutputStream
是一个 Java IO
中的输出流类,用于将数据写入到文件中。下面是它的源码分析:
6.1 构造函数
public FileOutputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null, false);
}
public FileOutputStream(String name, boolean append) throws FileNotFoundException {
this(name != null ? new File(name) : null, append);
}
public FileOutputStream(File file) throws FileNotFoundException {
this(file, false);
}
public FileOutputStream(File file, boolean append) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
this.fd = new FileDescriptor();
this.append = append;
open(name, append);
}
该类提供了多个构造函数,用户可以根据需要选择。其中,最重要的是最后一个构造函数,它接受一个 File 对象和一个 boolean 值,用于指定是否以追加模式打开文件。在构造函数中,会根据传入的文件路径进行权限检查,然后打开文件,并将文件描述符保存在一个 FileDescriptor
对象中。
6.2 write() 方法
public void write(int b) throws IOException {
write(new byte[] {(byte) b}, 0, 1);
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || off > b.length - len) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
Object traceContext = IoTrace.fileWriteBegin(path);
int written = 0;
try {
ensureOpen();
while (written < len) {
int bytesToWrite = Math.min(len - written, MAX_BUFFER_SIZE);
fd.sync(); // not required for O_APPEND
int bytesWritten = writeBytes(b, off + written, bytesToWrite);
written += bytesWritten;
if (bytesWritten != bytesToWrite) {
// If we didn't write what we wanted (and we're not closed), we should
// throw an IOException. But we should not throw it if we're closed.
// This is consistent with the behavior of SocketOutputStream.
if (written < len) {
throw new IOException("File system full");
}
break;
}
}
if (shouldCloseFD) {
// we will no longer be writing to this FileOutputStream, so we should
// release our hold on the underlying fd. This is not strictly necessary,
// but it's good citizenship. :-)
close();
}
} catch (IOException ioe) {
IoTrace.fileWriteEnd(traceContext, written);
throw ioe;
}
IoTrace.fileWriteEnd(traceContext, written);
}
在 write()
方法中,会先进行参数检查,然后调用 ensureOpen()
方法确保文件已经打开,接着使用一个循环来写入数据。其中,MAX_BUFFER_SIZE
的值为 8192,即一次最多写入 8KB 的数据。每轮循环会先调用 fd.sync() 方法将缓冲区的数据刷新到磁盘,再调用 writeBytes()
方法将数据写入文件中。在写入数据时,如果写入的字节数小于要写入的字节数,说明文件系统已经满了,此时会抛出一个 IOException 异常。
6.3 其他方法
FileOutputStream
还提供了一些其他的方法,比如 getFD()
方法可以获取文件描述符,close()
方法可以关闭输出流,flush()
方法可以将缓冲区的数据写入磁盘等。这些方法的实现比较简单,就不一一列举了。
6.4 源码截图
如下是FileOutputStream类在io包中的目录位置及部分源码展示:
总的来说,FileOutputStream
的源码比较简单,主要是在写入数据时需要进行一些缓冲区的操作和异常的处理。如果你需要写入文件,那么使用 FileOutputStream
是一个不错的选择。
全文小结
本文介绍了Java IO包中的一些基本知识和FileOutputStream
类的使用方法。在具体的介绍中,我们详细讲解了如何使用FileOutputStream
来写入文件,并给出了相应的示例代码。最后,我们也介绍了一些FileOutputStream
类的常用方法。通过本文的学习,我们可以更加轻松地操作文件流。
总结
Java IO包中的FileOutputStream
类为开发人员提供了一种非常便捷的写入文件的方式。通过本文对FileOutputStream
类的介绍,我们可以更加灵活地使用Java编程语言进行文件的操作。因此,在日常的Java开发中,我们应该熟练掌握FileOutputStream
类的使用方法。
附录源码
如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。
☀️建议/推荐你
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。
📣关于我
我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。
- 点赞
- 收藏
- 关注作者
评论(0)