简介
-
java标准io操作 Input Outout 输入 输出
- 流按照功能分为读写,按照方向分为输入输出,而方向的参照物为我们写的程序
- 输入流用来读取数据
- 输出流用来写出数据
- java.io.InputStream 是所有输入流的父类,规定了所有输入流应该具备的读取字节数据应该具备的读取字节数据的相关方法
- java.io.OutputStream 是所有字节输出流的父类
-
java将流分为了两大类 节点流和处理流
- 节点流:又称为低级流,是实际连接程序与另一端guan管道,负责实际搬运数据,读写一定是建立在低级流的基础上进行的
- 处理流:又称为高级流,不能独立存在(没意义),高级流一定会连接在其他流上,使得数据“流经”该流时对其jinx进行加工处理,简化我们对数据读写时的某些操作
-
文件流
- 文件流时一种低级流,用于读写文件数据,功能与RandomAccessFile一样,但是底层的读写方式不同,流是顺序读写的,而RAF是基于指针随机读写的
-
流分类
文件流
FileInputStream
- 文件流有两种常见的创建模式
-
FileOutputStream(String path)
-
FileOutputStream(File file)
以上两种方式创建时覆盖写模式 ,即若要操作的文件已经存在,会将该文件的数据清除,然后通过该流写出的数据作为该文件的数据
-
FileOutputStream(String path,boolean append)
-
FileOutputStream(File file,boolean append)
当第二个参数为true时,该文件为追加写模式
- 方法:
·close():
关闭此文件输出流并释放与次流有关的所有系统资源。
·write(byte[] b):
将b.length个字节从指定的byte数组写入次文件输入流中。
·write(byte[] b,int off,int len):
将指定byte数组中从偏移量off开始的len个字节写入此文件输出流。
· write(int b):
将指定字节写入此文件输出流
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt",true);//加上true追加写
String str = "我和佛文 ";
fos.write(str.getBytes());
System.out.println("写出完毕");
fos.close();
}
FileInputStream
- 简介:
从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。
用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader
。
- 构造方法:
- ·FileInputStream(File file):
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
- ·FileInputStream(String name):
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
- ~方法:
- ·close();void
关闭此文件输出流并释放与次流有关的所有系统资源。
- ·read();int
从此输入流中读取一个字节。
- ·read(byte[] b);int
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
- ·read(byte[] b,int off,int len);int
从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
byte [] data = new byte[200];
//获取返回值 得到实际读取的字节量
int len = fis.read(data);
String str = new String (data,0,len,"UTF-8");
System.out.println(str);
fis.close();
}
- 案例
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
FileOutputStream fos = new FileOutputStream("fos_cp.txt");
byte [] data = new byte[32];
int len = -1;
while((len=fis.read(data))!=-1) {
fos.write(data,0,len);
}
System.out.println("复制完毕");
fos.close();
fis.close();
}
缓冲流
(是一对高级流,缓冲字节输入输出流是用来加快读写效率的。)
BufferedOutputStream
- 简介:
该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
- 构造方法:
- ·BufferedOutputSteam():
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
- 方法:
- ·flush();void
刷新此缓冲的输出流。强制将缓冲区数据一次性输出。
·write(byte[] b,int off,int len);void
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。
·write();void
将指定的字节写入此缓冲的输出流。
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bos.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String str = "有份哦维护Nov我会韩国跑工地开工经济目标";
bos.write(str.getBytes("utf-8"));
//强制将缓冲区数据一次写出
bos.flush();
System.out.println("写出完毕!");
bos.close();
/*BufferedOutputStream bos = new BufferedOutputStream(fos);
String str = "我if较为今后IE我会就够额";
bos.write(str.getBytes("utf-8"));
bos.close();//close自带flush()*/
}
BufferedInputStream
- 构造方法:
- ·BufferedInputSteam():
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
~方法:
- ·read();void
- ·read(byte[] b,int off,int len);void
从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
- Demo
使用缓冲流完成文件复制操作
使用文件输入流读取源文件,使用文件。输出流往新文件里写,使用块读写形式,将源文件数据写入到新文件完成赋值操作。
public static void main(String[] args) throws IOException {
/*
* 使用文件输入流读取源文件,使用文件输出流往新文件里写,使用块读写形式将原文件数据写入到新文件完成复制操作
*/
FileOutputStream fos = new FileOutputStream("fos_cp.txt");
FileInputStream fis = new FileInputStream("fos.txt");
/*
* 使用了缓冲流读写时,我们就不需要关注必须用块读写加快效率了,因为缓冲流内部维护了一个字节数组,
* 最终会将我们读写操作转换为块读写加快块读写读写效率
*/
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte [] data = new byte[1024*10];
int len = bis.read(data);
while((len = bis.read(data))!=-1) {
bos.write(data,0,len);
}
System.out.println("复制完毕");
bos.close();
bis.close();
}
对象流
- 简介
对象流是一对高级流,可以方便我们读写java中的任何对象
对象输出流:可以将一组对象转换为字节后写出
对象输入流:可以将一组字节还原为对应的对象,前提是这组字节应该是是对象输出流将一个对象转换的字节
ObjectOutputStream
- 构造方法:
ObjectOutputStream()
可以将给定的对象转换为一组字节后写出。
- ~方法:
- ·flush():
刷新该流的缓冲。
- ·write(byte[] buf)
- ·write(byte[] buf,int off,int len)
- ·write(int val)
- ·writeInt(int val)……基本数据类型
- ·writeObject(Object obj);void
package io;
import java.io.Serializable;
import java.util.Arrays;
/**
* 使用当前类的实例测试对象流 读写对象的操作
*
* 当一个类的实例要被对象流进行续写时,要求该类必须实现Serializable接口()
* @author liuyanyan
*
*/
public class Person implements Serializable{
/*
* 当一个类实现了Serializable接口后,应当定义一个常量serialVersionUID
* 这个常量是序列化版本后。若不指定,编译器会在编译时按照当前类的结构生成一个版本后。但是若类的结构发生改变,版本号会跟着改变
* 序列化版本号直接影响对象输入流进行反序列化是否能成功
* 当反序列化的对象对当前类版本号一致,那么反序列化成功,否则反序列化会抛出异常
* 若当前类结构发生了变化,只要版本号没有改变,那么反序列化时会将仍然有的属性进行还原
*/
private static final long serialVersionUID = 2L;//序列化版本号,
private String name;
private int age;
private String gender;
private transient String [] otherInfo;//transient 告诉对象流在序列化的时候直接将其忽略
public Person(String name, int age, String gender, String[] otherInfo) {
this.name = name;
this.age = age;
this.gender = gender;
this.otherInfo = otherInfo;
}
public String toString() {
return "name=" + name + ", age=" + age + ", gender=" + gender + ", otherInfo="
+ Arrays.toString(otherInfo) ;
}
}
public static void main(String[] args) throws IOException {
String name = "苍老师";
int age = 18;
String gender = "女";
String[] otherInfo= {"是一名演员","爱好是写毛笔字"};
Person p = new Person(name, age, gender, otherInfo);
/*
* 将该person对象写入到文件person.obj中
*/
FileOutputStream fos = new FileOutputStream("./person.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
/*
* 对象输出流提供的方法
* void writeObject(Object o)
* 可以将给定的对象转换为一组字节后写出
*
*
* 下面代码实际上做了两件事
* 1:p对象先流经对象输出流,而对象输出流将该对象转换为了一组字节,这个过程称为对象序列化
* 2:转换的这组字节在流经文件输出流,然后写入了文件保存(写入磁盘),将数据写入磁盘做长久保存的过程称为数据持久化
*/
oos.writeObject(p);
System.out.println("写出完毕");
oos.close();
}
ObjectInputStream
- ~简介:
用于进行对象反序列化操作(可以将一组字节还原为对应的对象)。需要注意,对象流读取的字节必须是由对象输出流将一个对象序列化后的字节,否则进行反序列化时会抛出异常。
- ~构造方法:
- ObjectInputStream()
- ~方法:
- ·read(byte[] buf)
- ·read(byte[] buf,int off,int len)
- ·read(int val)
- ·readInt(int val)……基本数据类型
- ·readObject(Object obj);void
package io;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* 对象输入流,用于进行对象反序列化操作
* 需要注意:对象流读取字节必须是由对象输出流将一个对象序列化后的字符,否则进行反序列化是会抛出异常
* @author liuyanyan
*
*/
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Person p = (Person) ois.readObject();
System.out.println(p);
ois.close();
}
}
字符流:
- ~简介:
·读写单位是以字符为单位,所以字符流读写数据有一定的局限性,只能用于读写文本数据。非非文本数据不能使用字符流读取(如:图片、基本数据类型、mp3等数据)。
·Reader是所有字符输入流的父类,Writer是所有字符输出流的父类。
·是一对高级流,同时也是常用字符流实现类。
·在读写文本数据时,使用高级流进行流连接是非常重要的一环,起到承上启下的作用。因为几乎所有的字符流都只能连接在其他字符流上,而低级流基本上都是字节流,由于转换流可以连接字节流,而本身其自身又是字符流,所以起到将字符流与字节流“对接”的作用。
OutputStreamWriter(转换流)
- ~简介:
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
~构造方法:
- ·OutputStreamWriter(OutputStream out)
创建使用默认字符编码的OutputStreamWriter。
- ·OutputStreamWriter(OutputStream out,charset cs)
创建使用给定字符集的OutputStreamWriter。
- ~方法:
- ·close():
关闭此流,但要先刷新它。
- ·flush():
刷新该流的缓冲。
- ·write(char[] cbuf,int off,int len):
写入字符数组的某一部分。
- ·write(int c):
写入单个字符。
-
write(String str,int off,int len):
写入字符串的某一部分
package io;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* java将流按照读写单位划分为字节流和字符流
*
* 字符流:读写单位以字符为单位,所及字符流读写数据有一定局限性,只能用于读写文本数据。
* 非文本数据不能使用字符流读取(如图片,基本数据类型,mp3等数据)
*
* java.io.Reader,java.io.Eriter
* Reader: 是所有字符输入流的父类
* Writer:是所有字符输出流的父类
*
* 转换流:
* java.io.InputStreamReader
* java.io.OutputStreamWriter
* 他们是一对高级流,同时也是常用的字符流实现类
* 在读写文本数据时,使用高级流进行流连接中时非常重要的一环,起到承上启下的作用,因为几乎所有的字符流都只能连接在其他
* 流上,而基本上低级流都是字节流,由于转换流可以连接字节流,而本身其自身就是字符流,所以起到字符流与字节流“对接”
* 的作用
* @author liuyanyan
*
*/
/*
*
* 字符流只能读写文本文件
*/
public class OutputStreamWriterDemo1 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("osw.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
osw.write("费哦呜或飓风破解挂牌文件扶贫攻坚");
osw.write("我二姐坡国际阿房宫囧");
osw.write("1223");
System.out.println("写出完毕");
osw.close();
}
}
InputStreamReader(转换流)
- ~简介:
是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
~构造方法:
-
·InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。
- ·InputStreamReader(InputStream in,Charset cs)
创建一个使用给定字符集的InputStreamReader。
- ~方法:
- ·read():
读取单个字符。
- ·read(char[] cbuf,int off,int len):
将字符读入数组中的某一部分。
package io;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 转换流
* InputStreamReader可以读取字符
*
* @author liuyanyan
*
*/
public class InputStreamReaderDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("osw.txt");
InputStreamReader isw = new InputStreamReader(fis,"utf-8");
// int d = -1;
// if((d= isw.read())!=-1) {
// System.out.println((char)d);
// }
char[] data = new char[40];
int len = isw.read(data);
if((len= isw.read(data))!=-1) {
String str = new String (data,0,len);
System.out.println(str);
}
isw.close();
}
}
PrintWriter(缓冲字符流)
-
~简介:
具有自动行刷新的缓冲字符输出流,内部总是会连接BufferedWriter作为缓冲操作。
~构造方法:
- ·PrintWriter(File file)
- ·PrintWriter(String path)
- ·PrintWriter(OutputStream out, boolean autoFlush):
通过现有的 OutputStream 创建新的 PrintWriter。
- ~方法:
- ·append(char c)
将指定字符添加到此 writer。
- ·append(CharSequence csq, int start, int end)
将指定字符序列的子序列添加到此 writer。
- ·print(boolean b) 基本数据类型
打印 boolean 值。
- ·println(boolean x) 基本数据类型
打印 boolean 值,然后终止该行。
- ·write(char[] buf)
写入字符数组。
- ·write(char[] buf, int off, int len)
写入字符数组的某一部分。
- ·write(int c)
写入单个字符。
- ·write(String s)
写入字符串。
- ·write(String s, int off, int len)
写入字符串的某一部分。
- 案例1
package io;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
/**
* 缓冲字符流
* java.io.BufferedWriter
* java.io.BufferedRader
* 内部有缓冲区,可以快读写字符,并且可以按行读写字符串
*
*
* java.io.Printer
* 具有自动行刷新的缓冲字符输出流,内部总是会连接
* BufferedWriter作为缓冲流操作
*
*
* @author liuyanyan
*
*/
public class PrintWriterDemo3 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
/*
* PrinterWriter提供了直接对文件读写操作的构造方法
* PrintWriter(String path)
* Printwriter(File file)
*
*/
//向pw.txt文件中写出字符串.
PrintWriter pw = new PrintWriter("pw.txt","utf-8");
pw.println("joewf费价格为破甲弓二局");
pw.println("ewoihew佛和我GV会扣给我 ");
System.out.println("写入完毕");
pw.close();
}
}
- 案例2
package io;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
/**
* 在流连接中使用PrintWriter
* @author liuyanyan
*
*/
public class PrintWriterDemo4 {
public static void main(String[] args) throws FileNotFoundException {
//将字节写入文件
FileOutputStream fis = new FileOutputStream("pw2.txt");
//将字符转换为字符
OutputStreamWriter osw = new OutputStreamWriter(fis);
//写字符为块写操作 目的是为了加快读写效率
BufferedWriter bw = new BufferedWriter(osw);
//自动行刷新
PrintWriter pw = new PrintWriter(bw);
pw.write("诶我好怕观海卫");
pw.write("诶菲欧维护费哦呜");
System.out.println("写出完毕");
pw.close();
}
}
- 案例3
package io;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;
/**
* 使用PrintWriter,用流连接形式创建
* 完成记事本功能
* 将控制台输入的每一行字符串写入文件note.txt中
* @author liuyanyan
*
*/
/*
* 行刷新:自动调用flush
*/
public class PrintWriterDemo5 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
Scanner scn = new Scanner (System.in);
/*
* PrintWriter 的构造方法若第一个参数是一个流,那么就支持第二个参数,该参数为Boolean型,
* 若值为true时,那么pw就具有了自动刷新功能。
*
* 即:每当使用 println方法写出一行字符串后自动flush
* 注意:调用print方法是不会自动行刷新的!
*/
// PrintWriter pw = new PrintWriter("node1.txt");
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("node1.txt",true))));
System.out.println("请开始输入内容");
String str = null;
// System.out.println(str);
while(true) {
str=scn.nextLine();
if("exit".equals(str)) {
break;
}
pw.println(str);
}
System.out.println("写入完毕");
pw.close();
}
}
BufferedReader(缓冲字符输入流)
- ~简介:
可以按行读取字符串。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
- ~构造方法:
- ·BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
- ~方法:
- ·read() ;int
读取单个字符。
- ·read(char[] cbuf, int off, int len) ;int
将字符读入数组的某一部分。
- ·readLine() ;String
读取一个文本行。该方法会连续读取若干字符,当读取到换行符时,将之前读取的字符以字符串的形式返回,
若返回值为null,表示流的末尾 。
package io;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* java.io.BufferedReader
* 缓冲字符输入流,可以按行读取字符串
* @author liuyanyan
*
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
/*
* 将当前源代码读取出来并输出到控制台
*/
FileInputStream fis = new FileInputStream("src/io/BufferedReaderDemo.java");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
/*
* BufferedReader提供了直接读取一行字符串的方法
* String readline();
* 该方法会连续读取若干字符,当读取读取到换行符时,将之前读取的字符以字符串形式返回,
* 若返回值为null时,表示流的末尾
*/
String str = null;
while((str=br.readLine())!=null){
System.out.println(str);
}
br.close();
}
}