当前位置: 首页 > article >正文

【IO】读写文件(FileInputStream、FileOutputStream、FileReader、FileWriter、RandomAccessFile)

前言

Github:https://github.com/yihonglei/jdk-source-code-reading(java-io)

概述

在 Java 应用程序中,文件是一种常用的数据源或者存储数据的目标媒介。Java IO 读写文件的 IO 流分为两大类,字节流和字符流,

基于字节流的读写基类: InputStream和OutputStream

基于字符流的读写基类: Reader和Writer

关于文件读取的类关系图如下:

以下通过实例分析 Java 应用程序如何对文件进行读写操作。

一 读文件

我们可以根据文件类型,选择不同 io 子类来读取文件。

如果是二进制文件,使用 FileInputStream 读取;如果是文本文件,使用 FileReader 读取;

这两个类允许我们从文件开始至文件结尾一个字节或字符的读取文件,或者将读取的文件

写入字节数组或字符数组。如果我们想随机的读取文件内容,可以使用 RandomAccessFile 。

基于字节流读取文件步骤:

1、找到指定文件

2、根据文件创建文件输入流

3、创建字节数组

4、读取内容,放到字节数组里面

5、关闭输入流

读取一个文件,然后将文件内容以字符串形式输出。

package com.jpeony.io.bytestream;import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;/*** 读取文件:* 1、找到指定的文件* 2、根据文件创建文件的输入流* 3、创建字节数组* 4、读取内容,放到字节数组里面* 5、关闭输入流*/
public class FileRead {public static void main(String[] args) {// 构建指定文件File file = new File("C:\\mycode\\hello.txt");InputStream is = null;try {// 根据文件创建文件的输入流is = new FileInputStream(file);// 创建字节数组byte[] data = new byte[1024];// 读取内容,放到字节数组里面is.read(data);System.out.println("文件内容:" + new String(data));} catch (Exception e) {e.printStackTrace();} finally {try {// 关闭输入流is.close();} catch (Exception e) {e.printStackTrace();}}}
}

该例子中关于流的关闭并不完美,只是为了逻辑更清楚,才放在finally中关闭流,

其实关于流的关闭可以优化处理,优化后代码如下:

package com.jpeony.io.bytestream;import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;/*** 读取文件:* 1、找到指定的文件* 2、根据文件创建文件的输入流* 3、创建字节数组* 4、读取内容,放到字节数组里面* 5、关闭输入流*/
public class FileRead {public static void main(String[] args) {// 构建指定文件File file = new File("C:\\mycode\\hello.txt");// 根据文件创建文件的输入流try (InputStream is = new FileInputStream(file)) {// 创建字节数组byte[] data = new byte[1024];// 读取内容,放到字节数组里面is.read(data);System.out.println("文件内容:" + new String(data));} catch (Exception e) {e.printStackTrace();}}
}

优化后代码不需要在finally语句块中关闭流,把文件转换为流的处理放在try中自动关闭。

关于文件的读取,我们可以将文件流放在缓冲区中处理,效率会更高。

以上实例是基于字节流读取文件,而基于字符流读取文件其实与基于字节流大同小异。

基于字节流创建字节数组,基于字符流创建基于字符的数组。

基于字符流读取文件步骤:

1、找到指定文件

2、根据文件创建文件输入流

3、创建字符数组

4、读取内容,放到字符数组里面

5、关闭输入流

package com.jpeony.io.charstream;import java.io.*;/*** 读取文件:* 1、找到指定的文件* 2、根据文件创建文件的输入流* 3、创建字符数组* 4、读取内容,放到字符数组里面* 5、关闭输入流*/
public class FileReaderTest {public static void main(String[] args) {// 构建指定文件File file = new File("C:\\mycode\\hello.txt");// 根据文件创建文件的输入流try (Reader reader = new FileReader(file)) {// 创建字符数组char[] data = new char[1024];// 读取内容,放到字符数组里面reader.read(data);System.out.println("文件内容:" + new String(data));} catch (Exception e) {e.printStackTrace();}}
}

二 写文件

根据要写入数据是二进制数据或字符型数据选择 FileOutputStream 或 FileWriter。

我们可以一次写入一个字节或一个字符到文件中,也可以直接写入字节数组或字符数组到文件中。

数据按照我们写入的顺序存储在文件中。

基于字节流写入文件步骤:

1、找到指定的文件 

2、根据文件创建文件的输出流 

3、把内容转换成字节数组 

4、向文件写入内容 

5、关闭输入流  

package com.jpeony.io.bytestream;import java.io.*;/*** 写入文件:* 1、找到指定的文件* 2、根据文件创建文件的输出流* 3、把内容转换成字节数组* 4、向文件写入内容* 5、关闭输入流*/
public class FileWriter {public static void main(String[] args) {// 构建指定文件File file = new File("C:\\mycode\\hello.txt");// 根据文件创建文件的输出流try (OutputStream os = new FileOutputStream(file)) {String str = "我是中国人";// 把内容转换成字节数组byte[] data = str.getBytes();// 向文件写入内容os.write(data);} catch (Exception e) {e.printStackTrace();}}
}

将字符串转换为字节数组,通过输出流写入到指定文件中。

基于字符流写入文件步骤:

1、找到指定的文件 

2、根据文件创建文件的输出流 

3、把内容转换成字符数组 

4、向文件写入内容 

5、关闭输入流  

package com.jpeony.io.bytestream;import java.io.*;/*** 写入文件:* 1、找到指定的文件* 2、根据文件创建文件的输出流* 3、把内容转换成字符数组* 4、向文件写入内容* 5、关闭输入流*/
public class FileWriterTest {public static void main(String[] args) {// 构建指定文件File file = new File("C:\\mycode\\hello.txt");// 根据文件创建文件的输出流try (Writer writer = new FileWriter(file)) {String str = "我是中国人-FileWriter";// 把内容转换成字符数组char[] data = str.toCharArray();// 向文件写入内容writer.write(data);} catch (Exception e) {e.printStackTrace();}}
}

三 随机读写文件

package com.jpeony.io.charstream;import java.io.File;
import java.io.RandomAccessFile;public class RandomAccessFileTest {public static void main(String[] args) {File file = new File("C:\\mycode\\hello.txt");/*** model各个参数详解* r 代表以只读方式打开指定文件* rw 以读写方式打开指定文件* rws 读写方式打开,并对内容或元数据都同步写入底层存储设备* rwd 读写方式打开,对文件内容的更新同步更新至底层存储设备*/try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {//获取RandomAccessFile对象文件指针的位置,初始位置是0System.out.println("RandomAccessFile文件指针的初始位置:"+raf.getFilePointer());//移动文件指针位置raf.seek(0);byte[]  buff=new byte[1024];//用于保存实际读取的字节数int hasRead=0;//循环读取while((hasRead=raf.read(buff))>0){//打印读取的内容,并将字节转为字符串输入System.out.println(new String(buff,0,hasRead));}} catch (Exception e) {e.printStackTrace();}}
}

四 复制文件

拷贝的核心思想: 从源文件读取数据,通过循环写入到目标文件,从而实现文件复制。

package com.jpeony.io.bytestream;import java.io.*;/*** 实现思路:* 1、构建源文件与目标文件* 2、源文件创建输入流,目标文件创建输出流* 3、创建字节数组* 4、使用循环,源文件读取一部分内容,目标文件写入一部分内容,直到写完所有内容* 5、关闭源文件输入流,目标文件输出流*/
public class FileCopyTest {public static void main(String[] args) {// 构建源文件File file = new File("C:\\mycode\\hello.txt");// 构建目标文件File fileCopy = new File("C:\\mycode\\hello-copy.txt");InputStream in = null;OutputStream out = null;try {// 目标文件不存在就创建if (!(fileCopy.exists())) {fileCopy.createNewFile();}// 源文件创建输入流in = new FileInputStream(file);// 目标文件创建输出流out = new FileOutputStream(fileCopy, true);// 创建字节数组byte[] temp = new byte[1024];int length = 0;// 源文件读取一部分内容while ((length = in.read(temp)) != -1) {// 目标文件写入一部分内容out.write(temp, 0, length);}} catch (Exception e) {e.printStackTrace();} finally {try {// 关闭文件输入输出流in.close();out.close();} catch (Exception e) {e.printStackTrace();}}}
}

五 读取文件信息

文件信息包括创建时间,所有者等等信息,读取文件属性,从文件属性获取文件信息。

package com.jpeony.io.file;import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.util.Date;/*** @author yihonglei*/
public class FileInfoSimple {public static void main(String[] args) throws IOException {Path testPath = Paths.get("C:\\mycode\\hello.txt");BasicFileAttributeView basicView = Files.getFileAttributeView(testPath, BasicFileAttributeView.class);BasicFileAttributes basicFileAttributes = basicView.readAttributes();System.out.println("创建时间:" + new Date(basicFileAttributes.creationTime().toMillis()));System.out.println("最后访问时间:" + new Date(basicFileAttributes.lastAccessTime().toMillis()));System.out.println("最后修改时间:" + new Date(basicFileAttributes.lastModifiedTime().toMillis()));System.out.println("文件大小:" + basicFileAttributes.size());FileOwnerAttributeView ownerView = Files.getFileAttributeView(testPath, FileOwnerAttributeView.class);System.out.println("文件所有者:" + ownerView.getOwner());}
}

 

 

http://www.lryc.cn/news/2418985.html

相关文章:

  • 网络信息安全等级与标准_比较tcsec,cc及我国信息安全等级保护标准
  • 斗罗大陆武魂觉醒礼包码最新兑换码2024
  • 五笔字根表
  • (虚拟机)win10忘记密码重置_copy sethc,熬夜整理华为最新网络安全笔试题
  • 用移动硬盘当系统盘,即插即用
  • HTML的基本标签II
  • adns库的使用
  • JS检索下拉列表框中被选项目的索引号(selectedIndex)
  • C#报表控件ReportViewer
  • 权限表设计
  • 如何在本地设置www.xxx.com,使其允许访问
  • 解决MMC无法创建管理单元的问题!
  • 使用小马哥win10 激活工具激活后, 桌面上经常出现一个广告快捷方式的 解决方法...
  • Object-C 与C/C++的区别
  • 在word文档中如何自动生成目录,两种方法制作目录,总有一种适合你
  • 网工请自查!这十个技术问题还不会就out了
  • 使用Python Web(Django)和Bootstrap制作一款精美的“在线计算器”手把手教学——(基于Windows平台开发和部署,附完整代码和演示实例)
  • StretchDIBits函数
  • 人工智能--产生式表示法
  • VC-终止线程,ExitThread函数,TerminateThread函数,撤消线程,详解
  • eclipse-che01 安装eclipseche
  • 计算机网络自学指南,怒推荐一波,简直太全面了!
  • 小米更新显示非官方rom_魔趣ROM 安装刷入教程(小白新手)
  • 多路径软件常用操作(MPIO)
  • C语言学生成绩信息管理系统(超详细版)
  • OpenProcessToken
  • 前端框架Layui学习五:弹出层和数据表格
  • 原神童梦的切片解密攻略
  • VMware虚拟机安装Linux教程(超详细) | 阿里龙蜥OS (CentOS替代品)
  • 实战中绕过disable_functions执行命令