java io流 教程_Java基础教程:IO流与文件基础

Java:IO流与文件基础

说明:

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

走进流

什么是流

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

47b00c44ea163ff110c8ff94dca44bd2.png

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

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

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

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

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

IO流家族体系

对流的分类

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

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

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

家族体系图(原创)

72f9e0f0daff5c85275bcf3d8da1fe03.png

家族体系的顶层方法

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

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)            写入字符串的某一部分。

输出输入流的嵌套

说明

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

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

优点:

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

7d689f82e02e2bd5be2d1ae2c3b0de9f.png

着重介绍的几个过滤流

☑ BufferedInputStream

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

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

☑ BufferedOuputStream

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

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

☑ DataInputStream

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

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

常用流

思维导图

5db03a8b526eab2ed92b62475cbb9f5e.png

文件流

文件流包括

☐ 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类

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

36d188d7ba382adad33ef3deee6d9a3e.png

演示:

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):标准错误输出流

3e7a27b4e46ef715bc42b3b9034919db.png

程序从键盘读入数据:

☐ 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与其他顶层类的关系

b4a598638f17d590f5ab3ed31df1bf1b.png

构造方法

构造方法摘要

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接口,其对象才是可串行化的

(未完待续.....)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用数学模型向你解释离婚

A Mathematical Model of Sentimental Dynamics Accounting for Marital Dissolution解释离婚的情感动力学数学模型背景西方社会的离婚是普遍存在的。它提出了重大的科学和社会学问题&#xff0c;不管是理论上还是解决方式上。学者和问题处理专家认为存在一种情感关系热力学第二…

记一次 .NET医疗布草API程序 内存暴涨分析

一&#xff1a;背景 1. 讲故事我在年前写过一篇关于CPU爆高的分析文章 再记一次 应用服务器 CPU 暴高事故分析 &#xff0c;当时是给同济做项目升级&#xff0c;看过那篇文章的朋友应该知道&#xff0c;最后的结论是运维人员错误的将 IIS 应用程序池设成 32bit 导致了事故的发生…

自已做的第一个autoconf程序(不断完善中)

2019独角兽企业重金招聘Python工程师标准>>> 1、先写个简单的main函数&#xff0c;并按如下目录结构存放&#xff1a; timesync-- |--conf |--include |--lib |--src 2、在最上层目录下&#xff0c;执行autoscan&#xff0c;生成configure.scan&#xff0c;并改名为…

轻松看懂机器学习十大常用算法

通过本篇文章大家可以对ML的常用算法形成常识性的认识。没有代码&#xff0c;没有复杂的理论推导&#xff0c;仅是图解&#xff0c;介绍这些算法是什么以及如何应用&#xff08;例子主要是分类问题&#xff09;。以后有机会再对单个算法做深入地解析。今天的算法如下&#xff1…

MATLAB常用算法与应用实例分享来袭!

小天从大学开始接触数学建模&#xff0c;便开启资料收集功能。经过近几年的积累和沉淀&#xff0c;再加上对数学建模领域的深入研究&#xff0c;收集整理了丰富的数学建模资料&#xff0c;内容涵盖“MATLAB常用算法”&#xff0c;“MATLAB算法应用实例”等。截止到今天&#xf…

4个终于被破译的世界级密码

全世界有3.14 % 的人已经关注了数据与算法之美很多时候&#xff0c;一个设计精巧的密码就像数学难题一样&#xff0c;许许多多难以破解的密码让人青丝泛白&#xff0c;至今仍未见天日。不过&#xff0c;也有一些密码中的幸运儿&#xff0c;最终仍然迎来了真相大白的那天。秘密组…

java虚拟机工作原理图_Java虚拟机工作原理

首先我想从宏观上介绍一下Java虚拟机的工作原理。从最初的我们编写的Java源文件(.java文件)是如何一步步执行的&#xff0c;如下图所示&#xff0c;首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件&#xff0c;然后JRE加载Java字节码文件&#xff0c…

奇异值的物理意义是什么?

全世界有3.14 % 的人已经关注了数据与算法之美矩阵奇异值的物理意义是什么&#xff1f;或者说&#xff0c;奇异值形象一点的意义是什么&#xff1f;把m*n矩阵看作从m维空间到n维空间的一个线性映射&#xff0c;是否&#xff1a;各奇异向量就是坐标轴&#xff0c;奇异值就是对应…

WPF使用Animation仿WeChat(微信)播放语音消息

WPF开发者QQ群&#xff1a; 340500857 前言WPF使用Animation仿WeChat&#xff08;微信&#xff09;播放语音消息&#xff1f;效果图&#xff1a;创建MyAnimationForever.cs如下&#xff1a;public class MyAnimationForever : Control{private static Storyboard MyStory;priva…

epublib java_使用Epublib处理epub文件 | 学步园

通过wlw发布在我的博客funba.cn希望csdn能重新支持wlwEpublib是一个用于处理epub文件的java类库&#xff0c;可以对epub文件进行读写处理&#xff1b;而且提供了一个阅读器&#xff0c;可以直接运行(java -jar 方式)&#xff0c;并可以打开epub类型的文件进行阅读。1、这个例子…

机器学习的最佳学习路线,就在这里!

AI这个词相信大家都非常熟悉&#xff0c;近几年来人工智能圈子格外热闹&#xff0c;光是AlphoGo就让大家对它刮目相看。今天小天就来跟大家唠一唠如何进军人工智能的第一步——机器学习。在机器学习领域&#xff0c;Python已经成为了主流。一方面因为这门语言简单易上手&#x…

io流图解 java_详细讲解JAVA中的IO流

一、流的概念流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中&#xff0c;管道是一条不间断的字节流&#xff0c;用来实现程序或进程间的通信&#xff0c;或读写外围设备、外部文件等。一个流&#xff0c;必有源端和目的端&#xff0c;它们可以是计算机内存的某些区域&a…

分段函数 左右 f'正 不等于f'负 则f'导数不存在。所以不能推出f连续是否

根据单侧极限定理。当求分界处函数时。如果 f正f负 那么 f存在。 如果 f正&#xff01;f负 f不存在。 如果 f正或者f负不存在。 则f不一定不存在。单侧极限是可导的充分非必要条件。转载于:https://www.cnblogs.com/friends-wf/articles/2380690.html

BPM与Workflow的区别

ItemworkflowBPM流程管理周期设计、执行流程全周期&#xff0c;包括梳理、监控、分析目标用户群体编程人员业务人员、IT技术人员平台化设施流程引擎内核流程、组织、权限、表单、规则、门户、监控、分析等一体化的平台设施应用范围部门级&#xff0c;十余支企业级多级流程层次&…

21个令程序员泪流满面的瞬间【第二弹】

【1】明明我只修改了一行代码... 【2】千万不要随便乱动旧项目【3】提交了错误的分支【4】断点调试BUG【5】当我删除一个无用的代码块【6】糟糕&#xff0c;无法捕获这个BUG【7】当我刚好有一个好点子却被人打断【8】不小心打开了遗留项目【9】费力地捕获一个已知Bug【10】…

大厂出品免费图标资源站

IconPark 字节跳动出品矢量图标样式的开源图标库编程导航开源仓库&#xff1a;https://github.com/liyupi/code-navIconPark 图标库是一个通过技术驱动矢量图标样式的开源图标库&#xff0c;可以实现根据单一 SVG 源文件变换出多种主题&#xff0c; 具备丰富的分类、更轻量的代…

数学不好、英语不好、非本专业,想学python数据分析,能安排吗?

全世界有3.14 % 的人已经关注了数据与算法之美“非本专业想转型做数据分析&#xff0c;有救吗&#xff1f;”“数学不好&#xff0c;英语不好&#xff0c;想学Python数据分析&#xff0c;有救吗&#xff1f;”“不懂Python数据分析到底是什么&#xff0c;有救吗&#xff1f;”我…

在 .NET 中使用 C# 处理 YAML

在 .NET 中&#xff0c;可以使用 YamlDotNet 类库解析和生成 YAML 文件。YamlDotNet &#xff1a;https://github.com/aaubry/YamlDotNetNuGet 下载&#xff1a;https://www.nuget.org/packages/YamlDotNet/帮助文档&#xff1a;https://github.com/aaubry/YamlDotNet/wiki序列…

java读取图片缩略方法_java 图片缩略图的两种方法

最近网上看到两种不同的java图片缩略图的绘制方案第一种&#xff0c;使用Graphics().drawImage按照一定的比例重新绘制图像。Java代码package com.image.suoluetu;import java.io.*;import java.awt.*;import java.awt.image.*;import com.sun.image.codec.jpeg.*;public class…

Python项目可以有多大?最多可以有多少行代码?

全世界有3.14 % 的人已经关注了数据与算法之美导读&#xff1a;总是看到有人说&#xff0c;动态一时爽&#xff0c;重构火葬场。然而这世界上有的是著名的开源项目&#xff0c; 也有像 Github、Instagram 这样流量巨大的知名网站是基于动态语言开发的&#xff0c;经过了这么多年…