IO流【字节流、字符流、缓冲流、转换流、序列化流】
1、IO流
IO流就是把数据以流的形式在其它设备和内存中传输,就像水流;
根据流动方向课分为:
-
输入流 :把数据从
其他设备
上读取到内存
中的流。 -
输出流 :把数据从
内存
中写出到其他设备
上的流
2、字节流
所有的文件都是以二进制存储在计算机上的,都是一个字节一个字节的
字节输出流【OutPutStream】
java.io.OutputStream
抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地
-
public void close()
:关闭此输出流并释放与此流相关联的任何系统资源。 -
public void flush()
:刷新此输出流并强制任何缓冲的输出字节被写出。 -
public void write(byte[] b)
:将 b.length字节从指定的字节数组写入此输出流。 -
public void write(byte[] b, int off, int len)
:从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 -
public abstract void write(int b)
:将指定的字节输出流。
FileOutputStream类
一个参数的构造方法传递一个文件路径字符串或一个File对象,此构造方法是当文件存在时,会重写里面的内容,每次执行都是一个新的文件,不会追加写在里面,若要追加写,则应该用另一个构造方法。
-
public FileOutputStream(File file)
:创建文件输出流以写入由指定的 File对象表示的文件。 -
public FileOutputStream(String name)
: 创建文件输出流以指定的名称写入文件。
-
public FileOutputStream(File file, boolean append)
: 创建文件输出流以写入由指定的 File对象表示的文件。 -
public FileOutputStream(String name, boolean append)
: 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值,
true
表示追加数据,false
表示清空原有数据
public class Demo1 {
public static void main(String[] args) throws IOException {
//字节输出流,此构造方法数据不追加
FileOutputStream stream = new FileOutputStream(new File("E:\\aaa\\1.txt"));
//一次写一个字节
stream.write(97);
stream.write(98);
stream.write(99); //运行结果为:abc
//写一个字节数组
stream.write("你好".getBytes());//运行结果为:你好
//写入一个指定数组的指定索引处
stream.write("你好Hello".getBytes(),3,8);//运行结果为:Hello
stream.close();
}
}
追加写:
public class Demo2 {
public static void main(String[] args) throws IOException {
//字节输出流,此构造方法数据追加
FileOutputStream stream = new FileOutputStream(new File("E:\\aaa\\1.txt"),true);
//换行
stream.write("\r\n".getBytes());
//一次写一个字节
stream.write(97);
stream.write(98);
stream.write(99);
//写一个字节数组
stream.write("你好".getBytes());
//写入一个指定数组的指定索引处
stream.write("你好Hello".getBytes(),3,8);
stream.close();
}
}
Windows系统里,换行符号是
\r\n
字节输入流【InputStream】
-
public void close()
:关闭此输入流并释放与此流相关联的任何系统资源。 -
public abstract int read()
: 从输入流读取数据的下一个字节。 -
public int read(byte[] b)
: 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
FileInputStream类
-
FileInputStream(File file)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。 -
FileInputStream(String name)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
读取字节:read
方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1
public class Demo3 {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream(new File("E://aaa//1.txt"));
//读一个字节
// int read = fileInputStream.read();
// System.out.println((char) read);
//
// while((read = fileInputStream.read()) != -1){
// System.out.println((char)read);
// }
//数组读取
byte[] b = new byte[1024];
int len;
while((len=fileInputStream.read(b)) != -1){
System.out.println(new String(b,0,len));
}
// fileInputStream.read(b);
// System.out.println(new String(b));
fileInputStream.close();
}
}
练习:文件复制
将E:\aaa\bb\1.jpg文件复制到E:\aaa\cc\2.jpg下
public class Demo4 {
public static void main(String[] args) throws IOException {
long l = System.currentTimeMillis();
FileInputStream fileInputStream = new FileInputStream(new File("E:\\aaa\\bb\\1.jpg"));
FileOutputStream fileOutputStream = new FileOutputStream(new File("E:\\aaa\\cc\\2.jpg"));
byte[] b = new byte[1024];
int len;
while ((len = fileInputStream.read(b)) != -1){
fileOutputStream.write(b,0,len);
}
fileInputStream.close();
fileInputStream.close();
long l2 = System.currentTimeMillis();
System.out.println(l2-l);
}
}
流的关闭原则:先开后关,后开先关
3、字符流
字符输入流【Reader】
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中
-
public void close()
:关闭此流并释放与此流相关联的任何系统资源。 -
public int read()
: 从输入流读取一个字符。 -
public int read(char[] cbuf)
: 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中
FileReader类
java.io.FileReader
类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区
构造方法
-
FileReader(File file)
: 创建一个新的 FileReader ,给定要读取的File对象。 -
FileReader(String fileName)
: 创建一个新的 FileReader ,给定要读取的文件的名称
一个一个字符读取;
public class Demo5 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader(new File("E:\\aaa\\1.txt"));
int read = fileReader.read();
System.out.println((char) read);
while((read = fileReader.read()) != -1){
System.out.println((char) read);
}
fileReader.close();
}
}
字符输出流【Writer】
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地
-
void write(int c)
写入单个字符。 -
void write(char[] cbuf)
写入字符数组。 -
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分,off数组的开始索引,len写的字符个数。 -
void write(String str)
写入字符串。 -
void write(String str, int off, int len)
写入字符串的某一部分,off字符串的开始索引,len写的字符个数。 -
void flush()
刷新该流的缓冲。
FileWriter类
public class Demo6 {
public static void main(String[] args) throws IOException {
FileWriter fileWReader = new FileWriter(new File("E:\\aaa\\2.txt"));
fileWReader.write("你好java");
fileWReader.flush();
//fileWReader.close();
}
}
注意:
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要
flush
方法了
4、Properties类
方法:
-
public Object setProperty(String key, String value)
: 保存一对属性。 -
public String getProperty(String key)
:使用此属性列表中指定的键搜索属性值。 -
public Set<String> stringPropertyNames()
:所有键的名称的集合 -
public void load(InputStream inStream)
: 从字节输入流中读取键值对
public class Demo7 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("E:\\aaa\\2.txt"));
Set<String> key = properties.stringPropertyNames();
for (String s : key) {
System.out.println(s+"::"+ properties.getProperty(s));
}
}
}
/*
运行结果:
334::你好
file::java
*/
5、缓冲流
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率,缓冲流读写方法与基本的流是一致的。
字节缓冲流
public class Demo8 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:\\aaa\\bb\\1.zip"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("E:\\aaa\\cc\\2.zip"));
){
int b;
byte[] bytes = new byte[1024*3];
while((b = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes,0,b);
}
}catch (IOException e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("缓冲流复制时间:"+(end - start)+" 毫秒");
}
}
//4032毫秒
通过复制一个大文件发现,缓冲流的效率远远高于普通的字节流
字符缓冲流
public class Demo9 {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\aaa\\1.txt"));
String s = bufferedReader.readLine();
String s2 = bufferedReader.readLine();
String s3 = bufferedReader.readLine();
System.out.println(s);
System.out.println(s2);
System.out.println(s3);
bufferedReader.close();
}
}
练习:文本排序
将下图文件中的内容按序号排序:
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
9.今当远离,临表涕零,不知所言。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo10 {
public static void main(String[] args) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\aaa\\1.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\aaa\\3.txt"));
Map<String ,String> map = new HashMap<>();
String s = null;
while((s = bufferedReader.readLine()) != null){
String[] split = s.split("\\.");
map.put(split[0],split[1]);
}
Set<String> strings = map.keySet();
for (String string : strings) {
System.out.println(string+"::"+map.get(string));
}
//
for (int i = 1; i <= map.size(); i++) {
String st = String.valueOf(i);
String s1 = map.get(st);
bufferedWriter.write(st+"."+s1);
bufferedWriter.newLine();
}
bufferedWriter.close();
bufferedReader.close();
}
}
6、转换流
计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。
常见的编码集:GBK,ASCII字符集,utf-8,ISO-8859-1字符集
如果文件的编码和解码的编码集不同就会出现乱码。
InputStreamReader类&OutputStreamWriter类
转换流java.io.InputStreamReader
,是Reader的子类,是从字节流到字符流的桥梁。
转换流java.io.OutputStreamWriter
,是Writer的子类,是从字符流到字节流的桥梁。
默认编码集为:utf-8
import java.io.*;
public class Demo11 {
public static void main(String[] args) throws IOException {
//OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream("E:\\aaa\\6.text"),"Utf-8");
InputStreamReader ir = new InputStreamReader(new FileInputStream("E:\\aaa\\6.text"),"GBK");
int r ;
while((r = ir.read()) != -1){
System.out.print((char) r);
}
// ow.write("你好java");
//ow.close();
}
}
7、序列化
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据
、对象的类型
和对象中存储的属性
等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据
、对象的类型
和对象中存储的数据
信息,都可以用来在内存中创建对象
ObjectOutputStream类&ObjectInputStream类
java.io.ObjectOutputStream
类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。ObjectInputStream
反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。
被序列化或反序列化的对象的类需要实现Serializable
接口,否则就会出现序列化或反序列化异常
Person类:
import java.io.Serializable;
public class Person implements Serializable{
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
public class Demo1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//Person p = null//new Person("张三");
// ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("E:\\aaa\\a.txt"));
//
// oo.writeObject(p);
//
// oo.close();
ObjectInputStream oi = new ObjectInputStream(new FileInputStream("E:\\aaa\\a.txt"));
Object o = oi.readObject();
System.out.println(o.toString());
}
}
上一篇: Magento2 引入外部js文件
推荐阅读
-
IO流【字节流、字符流、缓冲流、转换流、序列化流】
-
16.IO流(字节流,字符流,数据流、对象流)
-
Java IO流之字符缓冲流实例详解
-
IO流(字节流,字符流,缓冲流)
-
Java之IO流(字节流,字符流)
-
字节流、字符流(IO流、字节流、字符流、异常处理、Properties)
-
缓冲字符流 java.io.BufferedWriter ,java.io.BufferedReader,缓冲字符输出流:PrintWriter
-
笔记 -11- File. IO概述 字节流 缓冲流 练习
-
JAVA-----IO篇四(缓冲流BufferedWriter以及BufferedReader、转换流outputStreamWriter以及inputStreamWriter)
-
IO流字节流,字符流,学习笔记 ;基础入门,一看就懂,一篇文章解决字节流好吧