Java中的IO操作涉及到的概念及相关类很多,很容易弄混,今天特来整理总结一下,并附上一份完整的文件操作的代码。

概念解析

读和写

流就是管道,向管道里面写数据用输出流:write
从管道里面读数据,用输入流:read

流的分类

流,按照不同的维度有不同的分类,按照从流中每次读取数据单位不同,划分为字节流字符流。
按照流-对应操作的角色的不同(是IO设备,还是其他流)是否能够直接向特定的IO设备如文件、网络、磁盘等,能够直接与这些进行读写的称之为节点流,
对节点流进一步封装的流,通过封装后的流来实现读写功能,处理流也被称为高级流。 

注意事项

1、流和数组不一样,不能通过索引读写数据。在流中,你也不能像数组那样前后移动读取数据,除非使用RandomAccessFile 处理文件。
2、流仅仅只是一个连续的数据流。流中的数据只能够顺序访问。当达到流末尾时,返回-1。
3、InputStream的read()方法返回一个字节大小,返回值的范围在0到255之间。
4、Reader的read()方法返回一个字符,会根据文本的编码,一次读取一个或者多个字节,返回值的范围在0到65535之间。
5、read(byte[])会尝试读取与给定字节数组容量一样大的字节数,返回值int表示已经读取过的字节数。如果InputStream内可读的数据不足以填满字节数组,那么数组剩余的部分将包含本次读取之前的数据。记得检查有多少数据实际被写入到了字节数组中。
6、read(byte, int offset, int length)同样将数据读取到字节数组中,不同的是,该方法从数组的offset位置开始,并且最多将length个字节写入到数组中。同样地,read(byte, int offset, int length)方法返回一个int变量,表示有多少字节已经被写入到字节数组中,所以请记得在读取数据前检查上一次调用read(byte, int offset, int length)的返回值。

示例代码

package com.lingyejun.io;

import java.io.*;

/**
* Created by Lingye on 2018/9/27 20:15
*/
public class FileStreamOperate { public static final String READ_UTF8_FILE_PATH = "D:\\input-utf8.txt";
public static final String READ_UNICODE_FILE_PATH = "D:\\input-unicode.txt";
public static final String WRITE_BYTES_FILE_PATH = "D:\\output-bytes.txt";
public static final String WRITE_CHARS_FILE_PATH = "D:\\output-char.txt"; /**
* 按照字节流的方式读取文件内容
*
* Step 1.根据文件路径,构建文件对象
* Step 2.创建输入流用来读取文件内容
* Step 3.创建字节数组来存放读取内容
* Step 4.关闭读取文件的输入流
*
* @return
*/
public void readFileByFileInputStream() {
System.out.println("=== readFileByFileInputStream Start ===");
// 构建文件对象
File inputFile = new File(READ_UTF8_FILE_PATH);
// 初始化输入流
InputStream inputStream = null;
try {
// 创建字节输入流
inputStream = new FileInputStream(inputFile);
// 读取到1KB字节数组中
byte[] buffer = new byte[100];
// 每次读取的字节数
int readLength;
// 读取数据并放到buffer数组中
while ((readLength = inputStream.read(buffer)) != -1) {
// UTF-8为变长编码,一个汉字占3个字节
System.out.println("本次读取" + readLength + "个字节数据内容为:" + new String(buffer));
}
} catch (FileNotFoundException e) {
// 文件未找到时异常处理
e.printStackTrace();
} catch (IOException e) {
// 读取过程中,删除文件会出此异常
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
// 关闭流过程,也有可能出现异常
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("=== readFileByFileInputStream End ===");
} /**
* 按照字符流的方式读取文件内容
*
* Step 1.根据文件路径,构建文件对象
* Step 2.创建字符输入流读取文件内容
* Step 3.创建字符数组来存放读取内容
* Step 4.关闭读取文件的字符输入流
*
* @return
*/
public void readFileByFileReader(){
System.out.println("=== readFileByFileReader Start ===");
// 根据路径拿到文件对象
File file = new File(READ_UTF8_FILE_PATH);
// 初始化字符输入流
Reader fileReader = null;
// 初始化存放读取内容的字符数组
char[] charArray = new char[100];
// 初始化一个字符
char once;
try {
fileReader = new FileReader(file);
// 一次读取一个数组长度的字符串
fileReader.read(charArray);
System.out.println(charArray);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
// 关闭流过程,也有可能出现异常
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("=== readFileByFileReader End ===");
} /**
* 通过字节流的方式写入信息到文件
*
* Step 1.根据文件路径,构建文件对象
* Step 2.创建字节输出流写出信息到文件
* Step 3.构造待写出的内容,并转为字节数组
* Step 4.关闭读取文件的字符输出流
*/
public void writeFileByFileOutputStream() {
System.out.println("=== writeFileByFileOutputStream Start ===");
// 创建写出文件
File file = new File(WRITE_BYTES_FILE_PATH);
// 初始化字节输出流
OutputStream outputStream = null;
// 写出内容
String outInfo = "写出测试";
// 转成字节数组
byte[] byteArray = outInfo.getBytes();
try {
// 创建输出字节流
outputStream = new FileOutputStream(file);
outputStream.write(byteArray);
System.out.println("按照字节流成功写出内容:"+outInfo);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
// 关闭写出流时,注意抓异常
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("=== writeFileByFileOutputStream End ===");
} /**
* 通过字符流的方式写入信息到文件
*
* Step 1.根据文件路径,构建文件对象
* Step 2.创建字符输出流写出信息到文件
* Step 3.构造待写出的内容,并转为字符数组
* Step 4.关闭读取文件的字符输出流
*/
public void writeFileByFileWriter(){
System.out.println("=== writeFileByFileWriter Start ===");
// 创建写出文件
File file = new File(WRITE_CHARS_FILE_PATH);
// 初始化字符输出流
Writer fileWriter = null;
String strInfo = "字符写出数据";
try {
// 创建输出字符流
fileWriter = new FileWriter(file);
// 写出内容
fileWriter.write(strInfo);
System.out.println("按照字符流成功写出内容:"+strInfo);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileWriter != null){
try {
// 关闭写出流时,注意抓异常
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("=== writeFileByFileWriter End ===");
} /**
* 任意读取文件内容
*/
public void randomAccessFile(){
System.out.println("=== randomAccessFile Start ===");
File file = new File(READ_UTF8_FILE_PATH);
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"r");
// 获取文件当前的指针位置
System.out.println("file now pointer is "+randomAccessFile.getFilePointer());
// 将文件指针设置到指定位置(绝对位置)
randomAccessFile.seek(3);
// 相对位置,相对于当前的位置,
randomAccessFile.skipBytes(3);
System.out.println("file now pointer is "+randomAccessFile.getFilePointer());
// 字节数组
byte[] buffer = new byte[17];
// off是指的写到buffer的数组的起始位置
randomAccessFile.read(buffer,0,buffer.length);
System.out.println(new String(buffer));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("=== randomAccessFile End ===");
} /**
* 通过字节流的方式将文件内容拷贝到另一个文件中
*
* Step 1.根据文件路径,构建源文件对象
* Step 2.根据文件路径,构造目的文件对象
* Step 3.创建字节输入流从源文件中读取信息
* Step 4.将读入到内存的信息再写出到目的文件中
* Step 5.拷贝完成后关闭输入输出流
*/
public void copyFile() {
System.out.println("=== copyFile Start ===");
// 输入文件对象
File inFile = new File(READ_UTF8_FILE_PATH);
// 输出文件对象
File outFile = new File(WRITE_BYTES_FILE_PATH);
// 初始化输入流
InputStream inputStream = null;
// 初始化输出流
OutputStream outputStream = null;
try {
// 将输入流怼到输入文件,使程序内存与磁盘建立联系
inputStream = new FileInputStream(inFile);
// 将输出流怼到输出文件,使程序内存与磁盘建立联系
outputStream = new FileOutputStream(outFile);
while (true) {
// 读取信息到内存
int temp = inputStream.read();
// 拷贝完成
if (temp == -1) {
break;
}
// 将内容拷贝到输出文件中
outputStream.write(temp);
}
System.out.println("拷贝文件成功完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
// 关闭输入流异常后,也要保证输出流关闭
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
System.out.println("=== copyFile End ===");
} public static void main(String[] args) {
FileStreamOperate fileStreamOperate = new FileStreamOperate();
// 按照字节流读取的话,一个汉字两个字节
fileStreamOperate.readFileByFileInputStream();
// 按照字符读取,java Unicode编码一个字符(不论字母还是汉字)两个字节
fileStreamOperate.readFileByFileReader();
// 采用任意读取的方式读取文件信息
fileStreamOperate.randomAccessFile();
// 按照字节流的方式写信息到文件
fileStreamOperate.writeFileByFileOutputStream();
// 按照字符流的方式写信息到文件
fileStreamOperate.writeFileByFileWriter();
// 拷贝文件
fileStreamOperate.copyFile();
}
}  

输入输出文件和执行结果

文件展示

执行结果

小结

通过本篇,我们学会了文件IO的一些常规操作方式,但是每次读取完文件后都需要在最后进行关闭流资源的close操作,这个操作不可省略,但是每次都写又显得十分啰嗦,有没有更加简便的方式呢,请看我的下一篇文章《try with resources简洁的异常捕获机制》

参考文章:https://blog.csdn.net/yhl_jxy/article/details/79272792

Java文件IO流的操作总结的更多相关文章

  1. Java - 文件(IO流)

    Java - 文件 (IO)   流的分类:     > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter     ...

  2. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  3. java中IO流的操作

    读取转换流--读取键盘录入中键盘录入一行数据并打印其大写,发现就是读一行数据的原理.也就是readLine方法.能不能直接使用readLine方法来完成键盘录入一行数据的读取呢?readLine方法是 ...

  4. Java基础-IO流对象之随机访问文件(RandomAccessFile)

    Java基础-IO流对象之随机访问文件(RandomAccessFile) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.RandomAccessFile简介 此类的实例支持对 ...

  5. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)

    Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...

  6. Java基础——IO流

    今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...

  7. Java---IO加强(3)-IO流的操作规律

    一般写关于操作文件的读取的几个通用步骤!!! 1.明确源和目的. 源:InputStream Reader 一定是被读取的. 目的:OutputStream Writer 一定是被写入的. 2.处理的 ...

  8. Java中IO流的总结

    有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...

  9. JAVA中IO流总结

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42119261 我想你对JAVA的IO流有所了解,平时使用的 ...

随机推荐

  1. laravel 5.3 多用户认证

    不知道对不对,乱来一下!!!! 1)laravel自带了一个用户认证系统,要使用的话,直接运行一下命令就可以用了 php artisan make:auth 会生成相应的控制器.路由和模版文件 2)数 ...

  2. IDEA Intellij 打开springboot项目 配置文件无法出现输入提示

    需要将java代码和资源文件进行标记

  3. 真 · windows环境下php7.0以上开启curl方法

    看这个说明之前,大家肯定百度在网上看到什么: 配置php.ini ,把curl_dll前的分号去掉 在php.ini中,查找extension=php_curl.dll ,找到后把它前面的分号去掉 之 ...

  4. POJ 3122 Pie

    题目大意: 给出n个pie的直径,有f+1个人,如果给每人分的大小相同(形状可以不同),每个人可以分多少.要求是分出来的每一份必须出自同一个pie,也就是说当pie大小为3,2,1,只能分出两个大小为 ...

  5. (1.1.6)UVA 10978 Let's Play Magic!(直叙式模拟)

    /* * UVA_10978.CPP * * Created on: 2013年10月6日 * Author: Administrator */ #include <iostream> # ...

  6. java基础---->java中变参函数的使用

    Java的变参函数实现实际上参数是一个数组,今天我们就简单的学习一下它的用法. java中的变参函数 一.它的使用方法如下: public class VariableParam { private ...

  7. Android SharedPreferences保存第一次的信息

    private void setHomeTimeZone() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPrefere ...

  8. 微信小游戏 查看egret的小游戏支持库版本

    在开发者工具 console输入egret.wxgame

  9. .net asp iis服务器如何让外部访问自己的网站

    1.控制面板-防火墙-高级设置-入站规则-右侧的BranchCache内容检索,右键启用规则.  

  10. Sublime Text 2/3 安装Emmet(Zencoding)以及常见使用,一种快速编写HTML/CSS代码的方法

    原文链接http://blog.csdn.net/shirley254/article/details/52336744