Java基础之文件的输入输出流操作
在介绍输入输出流之前,首先需要了解如何创建文件,创建文件夹以及遍历文件夹等各种操作,这里面不在一一介绍,主要介绍的是文件的输入输出流操作。
在起初学习文件操作之前,总是喜欢将输入输出弄混淆,后来通过看一些书以及一些视频,有了一些自己的心得体会,随后介绍一下,以便在我以后忘记的时候可以温习一下。
1.流的概念及分类
Java将所有传统的流模型(类或抽象类),都放在了Java.io包中,用来实现输入输出的功能。
这里面我们将流分成两种:输入流和输出流。
输入流:只能从中读取数据,而不能向其写入数据。代表:InputStream(字节输入流),Reader(字符输入流)。
输出流:只能向其写入数据,而不能从中读取数据。代表:OutputStream(字节输出流),Writer(字符输出流)。
流按照操作类型也可以分成两种:
字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的 。它操作的数据单元是8位的字节。
字符流 : 字符流只能操作纯字符数据,比较方便。它操作的数据单元是16位的字符。
在这个地方,我们需要弄清楚的就是什么是输入,什么是输出。如下图所示:
从Java程序指向文件,这个过程我们称为输出或者写入文件,从文件指向Java程序,这个过程我们称为输入或者读出文件。
在输入流和输出流中,我们主要掌握4个流文件的操作:InputStream,OutputStream,Reader,Writer。这四个类都是抽象类,前两个代表了字节的输入输出流,后两个代表字符的输入输出流,当我们调用的时候通常使用他们的子类来实现我们的类方法。
2.字节输出流(OutputStream)
字节输出流它有以下几个方法可以提供给它的子类使用(在输入输出流中,子类几乎没什么方法,都是调用父类的方法)
void close(): 关闭此输出流并释放与此流有关的所有系统资源。
void write(byte[] b): 将 b.length 个字节从指定的 byte 数组写入此输出流
void write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b) : 将指定的字节写入此输出流。
由于OutputStream是抽象类,因此我们在向文件写入(输出)字节的时候,需要用到它的子类FileOutputStream,接下来通过使用上面的方法,来实现字节流的输出操作。
关于FileOutputStream:
(1).写入数据文件,通过使用父类的方法,调用子类的对象
(2).FileOutputStream构造方法:
作用:绑定输出的输出目的
FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流,以追加的方式写入。
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append)
创建一个向具有指定 name 的文件中写入数据的输出文件流,以追加的方式写入。
(3).流对象的使用步骤:
1).创建流子类的对象,绑定数据目的。
2).调用流对象的方法write写
3).close释放资源
(4).注意事项:流对象的构造方法,可以用来创建文件,如果文件存在的情况下,直接覆盖原文件。
接下来通过代码来实现字节输出流的方法:
(1).输出单个字节
- package IO_File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class FileOutputStreamDemo {
- public static void main(String[] args) throws IOException{
- // TODO Auto-generated method stub
- //创建字节输出流的对象fos,并且指定了将直接写到哪里
- FileOutputStream fos = new FileOutputStream("d:\\output.txt");
- //写入一个字节,但是在文件中显示的是ASCII表中对应的值。
- fos.write(97);
- //关闭系统资源
- fos.close();
- }
- }
最终结果:
(2).输出字节数组
- package IO_File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class FileOutputStreamDemo {
- public static void main(String[] args) throws IOException{
- // TODO Auto-generated method stub
- //创建字节输出流的对象fos,并且指定了将直接写到哪里
- FileOutputStream fos = new FileOutputStream("d:\\output.txt");
- byte[] b = {97,98,99,100,101,102,103};
- //流对象的方法write写数据
- //将整个数组都写入到文件中
- fos.write(b);
- //写入了数组的一部分,从索引1的位置开始,写入了两个字节
- fos.write(b, 1, 2);
- //关闭资源
- fos.close();
- }
- }
最终结果:
3.字节输入流(InputStream)
字节输入流它有以下几个方法可以提供给它的子类使用(在输入输出流中,子类几乎没什么方法,都是调用父类的方法)
* abstract int read() : * 从输入流中读取数据的下一个字节,返回-1表示文件结束
* int read(byte[] b) * 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
* int read(byte[] b, int off, int len) * 将输入流中最多 len 个数据字节读入 byte 数组。 * void close() * 关闭此输入流并释放与该流关联的所有系统资源。
由于InputStream是抽象类,因此我们在从文件读取(输入)字节的时候,需要用到它的子类FileInputStream,接下来通过使用上面的方法,来实现字节流的输入操作。
关于FileInputStream:
在使用FileInputStream创建对象的时候,我们也需要为这个类绑定数据源(我们要读取的文件名)
FileInputStream的构造方法与上述的构造方法相似,里面的参数有两种类型:File类型对象,String类型对象。
输入流读取文件的操作步骤:
(1).创建字节输入流的子类对象
(2).调用读取方法read读取
(3).关闭资源
注意事项:read()方法每执行一次,就会自动的读取下一个字节。它的返回值是读取到的字节,如果没有字节可以读取了,那么返回-1。
下面用代码来实现FileInputStream的操作
(1).按照每个字节进行读取(效率相对低)
- package IO_File;
- import java.io.FileInputStream;
- import java.io.IOException;
- //字节输入流
- public class FileInputStreamDemo {
- public static void main(String[] args) throws IOException{
- FileInputStream fis = new FileInputStream("d:\\input.txt");
- //必须添加这个变量,直接使用fis.read作为输出,因为每次执行read()方法的时候,读取文件字节的指针都会向后移动一位。
- int hasRead = 0;
- //因为hasRead是每个字节的值,当为-1的时候,代表了整个文件都被读取。
- while((hasRead = fis.read())!=-1){
- System.out.println(hasRead);
- }
- //关闭文件资源
- fis.close();
- }
- }
最终结果:
文件中的数据:
现在再Java程序中的数据:
(2).读取字节数组
方法介绍:
1).int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
2).int read(byte[] b,int off,int len):将输入流中最多 len 个数据字节读入 byte 数组。
代码实现:
- package IO_File;
- import java.io.FileInputStream;
- import java.io.IOException;
- //字节输入流
- public class FileInputStreamDemo {
- public static void main(String[] args) throws IOException{
- FileInputStream fis = new FileInputStream("d:\\input.txt");
- //创建字节数组,相当于每次从文件中读取1024个字节保存到这个数据中。这里面一般都写1024
- byte[] b = new byte[1024];
- //必须添加这个变量,直接使用fis.read作为输出,因为每次执行read()方法的时候,读取文件字节的指针都会向后移动一位。
- int len = 0 ;
- //因为hasRead是每个字节的值,当为-1的时候,代表了整个文件都被读取。
- while( (len = fis.read(b)) !=-1){
- System.out.print(len);
- }
- fis.close();
- }
- }
最终的答案跟上述的结果相同,但是使用数组的执行效率比单个字节的效率高很多。
4.字符输出流(Writer)
由于Writer也是一个抽象类,因此我们用它的子类FileWriter来实现字符流的输出操作。
关于FileWriter:
(1).方法介绍:
void write(int c):写入单个字符。
void write(String str):写入字符串。
void write(String str, int off, int len):写入字符串的某一部分。
void write(char[] cbuf):写入字符数组。
abstract void write(char[] cbuf, int off, int len):写入字符数组的某一部分。
代码实现:
- package IO_File;
- import java.io.FileWriter;
- import java.io.IOException;
- public class FileWriterDemo {
- public static void main(String[] args) throws IOException{
- // TODO Auto-generated method stub
- FileWriter fw = new FileWriter("d://filewriter.txt");
- fw.write("123");
- //必须要加fw.flush(),代表刷新,不加这个语句不能写入到文件中
- fw.flush();
- fw.close();
- }
- }
最终结果:
5.字符输入流(Reader)
由于Reader也是一个抽象类,因此我们用它的子类FileReader来实现字符流的输出操作。
(1)方法介绍:
int read() * 读取单个字符
int read(char[] cbuf) * 将字符读入数组
abstract int read(char[] cbuf, int off, int len) * 将字符读入数组的某一部分。
代码实现:
- package IO_File;
- import java.io.FileReader;
- import java.io.IOException;
- public class FileReaderDemo {
- public static void main(String[] args) throws IOException{
- // TODO Auto-generated method stub
- FileReader fr = new FileReader("d://input.txt");
- int hasRead = 0;
- while((hasRead = fr.read())!=-1){
- System.out.print((char)hasRead);
- }
- fr.close();
- }
- }
最终结果:
字符流的输入输出与字节流的差不多,但是字符流只能操作文本文件,不能操作除了文本文件以外的文件,而字节流可以操作文本文件以及音乐,视频等文件,因此在平时的IO流中,我们使用字节流的操作更多一些。
6.文件的复制操作。(这里面我使用字节流的方式实现)
文件的复制操作简单的说就是将一个文件上的内容读取出来,并且将读取到的内容写入到另一个文件上,因此在文件的复制操作中,需要我们使用文件的输入和输出流操作。
注意事项:在复制文件的过程中,我们需要先读后写。
代码的实现方式如下:
- package IO_File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class FileCopy {
- public static void main(String[] args) throws IOException{
- // TODO Auto-generated method stub
- //文件复制,先读后写
- FileInputStream fis = new FileInputStream("d://input.txt");
- FileOutputStream fos = new FileOutputStream("d://1.txt");
- int hasRead = 0;
- while((hasRead = fis.read()) != -1){
- fos.write(hasRead);
- }
- fos.close();
- fis.close();
- }
- }
最终结果,将input.txt文件中的数据复制到了1.txt文件中。
为了我们共同进步,我这里有计算机专业的各种视频,
如果想要,关注我的公众号:念流声。私聊我,看到后给你连接(只放了一张图片,视频有很多,需要什么可以私聊问我,有的话就给你)。
Java基础之文件的输入输出流操作的更多相关文章
- Java修炼——文件字节输入输出流复制和缓冲流复制
一:文件字节输入输出流复制 首先明确数据源和目的文件,然后就是"中转站",最后就是关闭 package com.bjsxt.ioproject; import java.io.Fi ...
- Java基础复习笔记系列 七 IO操作
Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...
- Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)
Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...
- 【Java基础 】Java7 NIO Files,Path 操作文件
从Java1.0到1.3,我们在开发需要I/O支持的应用时,要面临以下问题: 没有数据缓冲区或通道的概念,开发人员要编程处理很多底层细节 I/O操作会被阻塞,扩展能力有限 所支持的字符集编码有限,需要 ...
- Java基础(二十四)Java IO(1)输入/输出流
在Java API中,可以从其中读入一个字节序列的对象称作输入流,而可以向其中写入一个字节序列的对象称为输出流. 输入流的指向称为源,程序从指向源的输入流中读取数据. 输出流的指向是字节要去的目的地, ...
- (JAVA)从零开始之--对象输入输出流ObjectInputStream、ObjectOutputStream(对象序列化与反序列化)
对象的输入输出流 : 主要的作用是用于写入对象信息与读取对象信息. 对象信息一旦写到文件上那么对象的信息就可以做到持久化了 对象的输出流: ObjectOutputStream 对象的输入流: Ob ...
- Java中IO流,输入输出流概述与总结
总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都是抽象类InputStream(字节输入 ...
- Java中的常用的输入输出流
Java中的输入输出流根据格式又可以分为字节流和字符流:(成对) 字节流:FileInputStream,FileOutputStream : BufferedInputStream,Buffe ...
- java对excel文件内容读写修改操作
Read.java package domain; import java.io.FileInputStream; import java.io.InputStream; import jxl.Cel ...
随机推荐
- [转帖]站点部署,IIS配置优化指南
站点部署,IIS配置优化指南 https://www.cnblogs.com/heyuquan/p/deploy-iis-set-performance-guide.html 挺值得学习的 毕竟之前很 ...
- NameNode格式化后HBase创建新表提示旧表已存在:table already exists
1.问题出现: 在格式化NameNode后,集群上安装的OpenTSDB的表(存在hbase中)都没有了,重新运行OpenTSDB预创建表步骤报错显示table already exists 2.原因 ...
- 小记---------Hadoop的MapReduce基础知识
MapReduce是一种分布式计算模型,主要用于搜索领域,解决海量数据的计算问题 MR由两个阶段组成:Map和Reduce,用户只需要实现map()和reduce()两个函数,即可实现分布式计算. 两 ...
- C++中的异常处理(上)
1,C++ 内置了异常处理的语法元素 try ... catch ...: 1,try 语句处理正常代码逻辑: 2,catch 语句处理异常情况: 3,try 语句中的异常由对应的 catch 语句处 ...
- Vue 系列(一): Vue + Echarts 开发可复用的柱形图组件
目录 前置条件 安装echarts 引入echarts 柱形图组件开发 在何时初始化组件? 完整的代码 记得注册组件!!! 本文归柯三(kesan)所有,转载请注明出处 https://www.cnb ...
- Python 描述符 (descriptor)
1.什么是描述符? 描述符是Python新式类的关键点之一,它为对象属性提供强大的API,你可以认为描述符是表示对象属性的一个代理.当需要属性时,可根据你遇到的情况,通过描述符进行访问他(摘自Pyth ...
- TCP的三次握手与四次挥手理解及面试题
TCP的三次握手与四次挥手理解及面试题(很全面) 转载自:https://blog.csdn.net/qq_38950316/article/details/81087809 本文经过借鉴书籍资料.他 ...
- php邮件防注入以及实现经典代码
<?php function spamcheck($field) { // filter_var() 过滤 e-mail // 使用 FILTER_SANITIZE_EMAIL ...
- 关于在docker中配置elasticsearch容器的方法
一.关于docker的安装,注意几点 1.如果系统是Win10家庭版,是没有Hyper-V的,所以无法安装docker(运行docker安装包会报错),为此docker官网提供的解决方法是安装dock ...
- java线程中的同步锁和互斥锁有什么区别?
两者都包括对资源的独占. 区别是 1:互斥是通过竞争对资源的独占使用,彼此没有什么关系,也没有固定的执行顺序. 2:同步是线程通过一定的逻辑顺序占有资源,有一定的合作关系去完成任务.