Java:IO流与文件基础

说明:

本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦。

走进流

什么是流

流:指的是从源到目的地的字节的有序序列。

在Java中,可以从其中读取一个字节序列的对象称作 输入流,可以向其中写入一个字节序列的对象称作 输出流。

☑ 这些字节序列的来源可以是:文件、网络连接、内存块等。

☑ 抽象类InputStream和OutputStream是构成输入/输出(I/O)的基础。

☑ 因为面向字节的流不便于处理以Unicode形式存储的信息(字符),所以从抽象类Reader 和 Writer中继承出来一个专门处理字符流的类层次结构。

☑ 适配器类InputStreamReader将InputStream转换为Reader,OutputStreamWriter将OutputStream转换为Writer

IO流家族体系

对流的分类

☑ 依据流相对于程序的另一个端点的不同:☐ 节点流(全黄):以特定源(如磁盘文件、内存某区域或线程之间的管道)为端点构造的输入/输出流

☐ 过滤流(半黄):以其他已存在的流为端点构造的输入/输出流。☑ 依据流中的数据单位不同:☐ 字节流:流中的数据以8位字节为单位进行读写,以InputStream和OutputStream为共同父类

☐ 字符流:流中的数据以16位字符为单位进行读写,以Reader和Writer为共同父类

家族体系图(原创)

家族体系的顶层方法

顶层方法不是很多,但是需要我们去记住,下面列出了所有的顶层方法,遇到问题是结合上图和下表可以清理思路。

A.abstract classOutputStream

返回类型方法及解释

void

close()            关闭此输出流并释放与此流有关的所有系统资源。

void

flush()            刷新此输出流并强制写出所有缓冲的输出字节。

void

write(byte[] b)            将 b.length 个字节从指定的 byte 数组写入此输出流。

void

write(byte[] b, int off, int len)            将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

abstract  void

write(int b)            将指定的字节写入此输出流。

B.abstract classInputStream

返回类型方法及解释

int

available()            返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。

void

close()            关闭此输入流并释放与该流关联的所有系统资源。

void

mark(int readlimit)            在此输入流中标记当前的位置。

boolean

markSupported()            测试此输入流是否支持 mark 和 reset 方法。

abstract  int

read()            从输入流中读取数据的下一个字节。

int

read(byte[] b)            从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

int

read(byte[] b, int off, int len)            将输入流中最多 len 个数据字节读入 byte 数组。

void

reset()            将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。

long

skip(long n)            跳过和丢弃此输入流中数据的 n 个字节。

C.abstract class Reader

返回类型方法及解释

abstract  void

close()            关闭该流并释放与之关联的所有资源。

void

mark(int readAheadLimit)            标记流中的当前位置。

boolean

markSupported()            判断此流是否支持 mark() 操作。

int

read()            读取单个字符。

int

read(char[] cbuf)            将字符读入数组。

abstract  int

read(char[] cbuf, int off, int len)            将字符读入数组的某一部分。

int

read(CharBuffer target)            试图将字符读入指定的字符缓冲区。

boolean

ready()            判断是否准备读取此流。

void

reset()            重置该流。

long

skip(long n)            跳过字符。

D.abstract classWriter

返回类型方法及注释

Writer

append(char c)            将指定字符添加到此 writer。

Writer

append(CharSequence csq)            将指定字符序列添加到此 writer。

Writer

append(CharSequence csq, int start, int end)            将指定字符序列的子序列添加到此 writer.Appendable。

abstract  void

close()            关闭此流,但要先刷新它。

abstract  void

flush()            刷新该流的缓冲。

void

write(char[] cbuf)            写入字符数组。

abstract  void

write(char[] cbuf, int off, int len)            写入字符数组的某一部分。

void

write(int c)            写入单个字符。

void

write(String str)            写入字符串。

void

write(String str, int off, int len)            写入字符串的某一部分。

输出输入流的嵌套

说明

单独使用节点流的情况在程序中较少出现。

一般常通过过滤流将多个流套接在一起,利用各种流的特性共同处理数据,套接的多个流构成了一个流链

优点:

方便数据的处理并提高处理的效率。

着重介绍的几个过滤流

☑ BufferedInputStream

☐ 在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。

☐ 在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。

☑ BufferedOuputStream

☐ 该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

☑ BufferedReader和BufferedWriter同样也是提供缓存区。

☑ DataInputStream

☐ 包含用于读取基本类型数据的全部接口

说明:所有的这些在下面我们都会重新强调并实现。

常用流

思维导图

文件流

文件流包括

☐ FileReader/FileWriter类

☐ FileInputStream/FileOutputStream类

创建文件流

☐FileInputStream(File file)

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

☐FileInputStream(String name)

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

实例

public class FileCopy{

public static void main(String[] args) throws IOException{

FileInputStream in=new FileInputStream("FileCopy.java");

FileOutputStream out=new FileOutputStream("FileCopy.txt");

int c;

while( (c=in.read())!=-1)

out.write(c);

in.close();

out.close();

}

}

缓存流

说明:

缓存流是过滤流,以InputStream/OutputStream为前端流,并可指定缓冲区大小,如:

public BufferedInputStream(InputStream in)

public BufferedInputStream(InputStream in, int size)

BufferedReader增加readLine()

BufferedWriter增加newLine():写入一个换行符。

演示:

public class BufferedIO{

public static void main(String[] args) throws IOException{

BufferedReader in=new BufferedReader(

new FileReader("BufferedIO.java"));

PrintWriter out=new PrintWriter( new BufferedWriter(

new FileWriter("BufferedIO.txt")));

String s;

int linecnt=1;

StringBuilder sb=new StringBuilder();

while((s=in.readLine())!=null){

sb.append(linecnt+":"+s+"\n");

out.println(linecnt+":"+s);

linecnt++;

}

in.close();

out.close();

System.out.print(sb.toString());

}

}

说明:

PrintWriter

向文本输出流打印对象的格式化表示形式,即在写入的同时可以对写入的数据进行格式化。

数据流

数据流包括:

DataInputStream/DataOutputStream类

读写基本数据类型的接口方法:

演示:

public class DataIO{

public static void main(String[] args) throws IOException{

DataOutputStream out=new DataOutputStream(

new BufferedOutputStream(new FileOutputStream("data.txt")));

out.writeBoolean(false); out.writeChar('c');

out.writeByte(1); out.writeShort(2);

out.writeInt(3); out.writeLong(4L);

out.writeFloat(5.0f); out.writeDouble(6.0);

out.writeUTF("hello world!"); out.close();

DataInputStream in=new DataInputStream(

new BufferedInputStream( new FileInputStream("data.txt")));

System.out.println(in.readBoolean()+";"+in.readChar()+";");

System.out.println(in.readByte()+";"+in.readShort()+";");

System.out.println(+in.readInt()+";"+in.readLong());

System.out.println(in.readFloat()+";"+in.readDouble()+";");

System.out.println(in.readUTF()); in.close();

}

说明:

☑readUTF()与writeUTF()

writeBytes(String)和writeChars(String)方法在DataInputStream中没有对应的方法恢复出String

用DataOutputStream写字符串并使得DataInputStream能恢复出字符串的方法是使用writeUTF()和readUTF()

☑ UTF-8

ASCII字符→单字节形式;非ASCII字符→多字节形式

字符串长度→UTF-8字符串的前两字节中

Java中使用的是UTF-8的变体,UTF-8只是读写过程中的字符串形式,程序中Unicode

标准IO:

标准输入:键盘

标准输出:加载Java程序的命令窗口

Java在System类中定义了三个标准I/O流,是System类的三个静态变量:

☐System.in(public static final InputStream in):标准输入流

☐System.out(public static final PrintStream out):标准输出流

☐System.err(public static final PrintStream err):标准错误输出流

程序从键盘读入数据:

☐ int ch=System.in.read();

☐ System.in.read()从键盘缓冲区读入一个字节的数据,返回的是整型值(低位字节为输入数据,高位字节全为零)

☐ System.in.read()的执行使得整个程序被挂起,直到用户从键盘输入数据才继续运行

☐ 从键盘逐行读入:嵌套BufferedReader和InputStreamReader

实例:

public class StandardIO {

public static void main(String[] args) {

String s;

BufferedReader in = new BufferedReader(

new InputStreamReader(System.in));

System.out.println("Please input: ");

try {

s = in.readLine();

while (!s.equals("exit")) {

System.out.println(" read: " + s);

s = in.readLine();

}

System.out.println("End of Inputting");

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

java.util.Scanner类:从控制台读取输入

说明

Scanner sc=new Scanner(System.in);

Scanner将控制台输入按照分隔符模式进行分割,分隔符模式默认为匹配空格

扫描结果通过各种next*()方法转化为不同类型的值

next()获取一个字符串

nextByte() 获取一个byte类型的整数

nextShort() 获取一个short类型的整数

nextInt() 获取一个int类型的整数

nextLong() 获取一个long类型的整数

nextFloat() 获取一个float类型的数

nextDouble() 获取一个double类型的数

nextLine() 获取一行文本(即以回车键为结束标志)

输入输出的重定向

System.setIn(InputStream)

System.setOut(PrintStream)

System.setErr(PrintStream)

随机存取文件

说明

到目前为止所学习的Java流式输入/输出都是顺序访问流,即流中的数据必须按顺序进行读写当需要随机读写磁盘文件中的内容时,用RandomAccessFile类(既可对文件读,又可对文件写)

RandomAccessFile与其他顶层类的关系

构造方法

构造方法摘要

RandomAccessFile(File file, String mode)            创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。

RandomAccessFile(String name, String mode)            创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

mode值含意

"r"

以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。

"rw"

打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。

"rws"

打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。

"rwd"

打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。

操作

文件指针操作

long getFilePointer()//返回当前文件指针

void seek(long pos)//文件指针定位到指定位置

long length()//返回文件长度

int skipBytes(int n)//从当前位置开始跳过n字节

读操作(实现了DataInput接口)

readBoolean(), readChar(), readInt(), readLong(), readFloat(), readDouble(), readLine(), readUTF()等

写操作(实现了DataOutput接口)

writeBoolean(), writeChar(), writeUTF(), writeInt(), writeLong(), writeFloat(), writeDouble()等

实例

public class RandomAccessTest {

public static void main(String[] args) throws IOException {

long filePoint = 0;

String s;

RandomAccessFile file = new RandomAccessFile(

"RandomAccessTest.java", "r");

long fileLength = file.length(); // 获取文件长度

while (filePoint < fileLength) {

s = file.readLine(); // 读一行字符,并移动文件指针

System.out.println(s); // 输出显示读入的一行字符

file.skipBytes(5);

filePoint = file.getFilePointer(); // 获取当前文件指针

}

file.close();

}

}

对象的串行化

将对象保存到外存,称为对象的永久化。对象永久化的关键是将对象的状态以一种串行格式表示出来,以便以后读取能够将该对象重构出来。对Java对象的这一读写过程称为对象的串行化。

常在下列情况下使用

1.Java远程方法调用(Remote Method Invocation)

2.Java Bean / EJB

3.对象永久化

实现串行化

• 用ObjectOutputStream/ObjectInputStream实现对象的串行化

◇ 通过ObjectOutputStream的writeObject方法将一个对象写入到流中

▪ public final void writeObject(Object obj) throws IOException

◇ 通过ObjectInputStream的readObject方法将一个对象从对象流中读出

▪ public final Object readObject() throws IOException, ClassNotFoundException

◇ ObjectOutputStream实现了java.io.DataOutput接口

◇ ectInputStream实现了java.io.DataInput接口

实例

/*输出对象*/

public class SerializeDate {

SerializeDate( ){

Date d = new Date( );

try {

ObjectOutputStream s= new ObjectOutputStream(

new FileOutputStream(“date.ser”));

s.writeObject(d);

s.close( );

}catch( IOException e){

e.printStackTrace( );

}

}

public static void main(String args[]){

SerializeDate b = new SerializeDate();

}

}

/*输入对象*/

public class UnSerializeDate {

Date d = null;

UnSerializeDate() {

try {

ObjectInputStream s = new ObjectInputStream(

new FileInputStream("date.ser"));

Object o=s.readObject();

if(o instanceof Date)

d = (Date) o;

s.close();

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

UnSerializeDate us = new UnSerializeDate();

System.out.println(us.d.toString());

}

}

注意:

一个类只有实现了Serializable接口,其对象才是可串行化的

(未完待续.....)

java io流 教程_Java基础教程:IO流与文件基础相关推荐

  1. java io流顶层_Java中的IO流(一)

    一,IO流的分类 A,按照操作的对象不同可分为字节流与字符流 B,按照流的方向不同可分为输入(指从外部存储设备拿文件到内存)流也叫读与输出(指从内存把文件写入到外部存储设备)流也叫写 注:字节流可以操 ...

  2. java io的异常_Java 异常与IO流

    一.异常 想想一下代码会发生什么? public static voidmain(String[] args) {int a = 10;int b = 0; System.out.println(a/ ...

  3. java流框架_Java中的IO框架流二

    1      IO(二)No19 [ 缓冲流:内置了缓冲区,对现有的流对象进行了封装,实现了高效的读写操作并增强了功能 字节缓冲流 BufferedInputStream BufferedOutput ...

  4. java joinpoint教程_Java的教程

    Java编程语言 Java编程语言中,左侧的导航栏(Java编程语言),可以快速定位文章的内容.这篇文章主要汇总以下: Java编程语言学习:Java的概述,Java的基础,Java面向对象的概念,J ...

  5. java nio教程_Java NIO教程

    java nio教程 1.简介 Java NIO是Java 1.4引入的一个库. 自从Java NIO推出以来,它提供了另一种方法来处理I / O和网络事务. 它被认为是Java网络和Java IO库 ...

  6. java反射教程_Java反射教程

    java反射教程 在本教程中,我主要编写一些示例来介绍Java反射可以做什么. 希望它可以给您这个概念的概述. 请留下您的评论以寻求建议. 什么是反射? 简而言之,反射是程序在运行时检查和修改对象的结 ...

  7. java音频教程_Java如何使用IO流实现音频的剪切和拼接的示例代码

    这篇文章主要为大家详细介绍了Java使用IO流实现音频的剪切和拼接,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 需求:使用IO流将指定目录下的若干个音频文件的高潮部分,进行剪切,并重新拼接成一首 ...

  8. java字符流输出流_JAVA语言之IO流字符串输入输出流

    本文主要向大家介绍了JAVA语言之IO流字符串输入输出流,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 概述 StringReader 字符输入流 和CharArrayReader类 ...

  9. java 弹出另存为_java如何实现 io流传输过来的文件,提示另存为弹出窗口?

    java如何实现 io流传输过来的文件,提示另存为弹出窗口? mip版  关注:166  答案:6  悬赏:0 解决时间 2021-01-24 22:00 已解决 2021-01-24 11:06 最 ...

  10. java 流式_Java核心教程5: 流式编程

    本次课程的标题不像之前那样易懂,是一个陌生的概念,"流式编程"是个什么东西? 在了解流式编程之前先思考一下"流",水流.电流.人流,这些都是流.而流式编程则是让 ...

最新文章

  1. Python创建virtualenv(虚拟环境)方法
  2. collections模块简介
  3. 图解LanHelper 使用
  4. 超级封装RecyclerView的适配器Adapter 只需二三十行代码
  5. 将文件从HDFS复制到本地
  6. Angular filter test
  7. oracle处理回车换行符
  8. java script的trim_Javascript中实现trim()函数的两种方法
  9. [Codeforces Round #254 div1] C.DZY Loves Colors 【线段树】
  10. 必须了解的Web安全知识(第一部分:HTTPS,TLS,SSL,CORS,CSP)
  11. 细说嵌入式Linux文件系统的制作方法
  12. apache shiro jar包_Shiro(一)
  13. silic php 马,Silic PHP大马Cookie欺骗漏洞
  14. matlab空间计量AIC准则,关于AIC准则
  15. 收藏 | 基于深度学习的图像匹配技术一览
  16. 关于灰排线两端压接类型简介
  17. Springboot 前后端交互 Long类型传输 前端获取数据受限
  18. 双系统,win7重装后,找回linux
  19. Python入门第3课——变量类型(只读课堂)
  20. 计算机基础教研活动记录,信息技术教研活动记录

热门文章

  1. 使用C#读写结构化的二进制文件
  2. 深入理解C#:编程技巧总结(一)
  3. 替代反射调用的几种方式及性能测试
  4. 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(一)-- 起步
  5. 基于mysql数据库的应用_MySQL数据库应用
  6. [转]Redis持久化存储(AOF与RDB两种模式)
  7. Chrome 双击关闭标签,新窗口打开新地址,一个插件搞定,安装方便,自带hosts
  8. python之sys.argv获取命令行的参数
  9. linux之tar命令使用总结
  10. Android之如何解决ScrollView起始位置不是最顶部的解决办法