开始时间2020-11-22
IO流
1.Io流,什么是Io?
I: Input
o : output
通过Io可以完成硬盘文件的读和写。
这在其他语言中也经常有,参考一下自己之前写的Python的文件读写
以及VBA的文件读写
2.Io流的分类?
按照流的方向进行分类:
以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read) .
从内存中出来,叫做输出(output)。或者叫做写(write).
另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频等
有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取
普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读: 'a’字符('a’字符在windows系统中占用1个字节。)第二次读:'中字符('中’字符在windows系统中占用2个字节。)
假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到a
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。
char在Java中是两个字节,但是在Windows中占用一个字节
Java中所有的流都在Java.io.*下
主要研究:
new流文件
调用流对象是读还是写
主要有四大家族:
- InputStream
- OutputStream
- BufferedReader
- BufferedWriter
类名以Stream的都是字节流
以Reader/Writer结尾的为字符流
这四种都是抽象类
所有流都实现了Java.io.Closeable接口,都是可关闭的,都有close()方法
用完都要关,这和其他语言也是一样的。
所有输出流都实现了
Java.io.flushable接口,都是可刷新的,都有flush()方法
刷新的作用就是把未输出的数据强行输出完(清空管道)
常用的流:
- 文件流:
- java.io.FileInputstream
- java.io.Fileoutputstream
- java.io.FileReader
- java.io.Filewriter
- 转换流(将字节流转为字符流):
- java .io.InputstreanReader
- java.io.Outputstreamwriter
- 缓冲流
- java.io.BufferedReader
- java.io.Bufferedwriter
- java.io.BufferedInputstream
- java.io.Bufferedoutputstream
- 数据流
- java.io.DataInputstream
- java.io.Dataoutputstream
- 标准输出流
- java.io.Printwriter
- java.io.Printstream
- 对象专属流
- java.io.objectInputstream
- java.io.objectoutputstream
读取示例FileInputStream
package BUPT20201122;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
Java.io.FileInputStream
*/
public class IOStreamTest01 {
public static void main(String[] args) throws FileNotFoundException {
//创建输入流对象
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("E:\\编程学习\\Java学习\\Java代码学习\\Java代码.txt");
int readDate = fileInputStream.read();
int readDate2 = fileInputStream.read();
//返回值是读取到的字节本身
System.out.println(readDate);
//往后面移动了一位
System.out.println(readDate2);
//读到最后会返回-1
int readDate3;
while ((readDate3 = fileInputStream.read()) != -1) {
System.out.println(readDate3);
}
//这里也有异常,需要抛一下
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
//关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
上述代码每次只读了一个字符,这样效率低,改为用数组读,一次多个字符
package BUPT20201122;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
int read(byte[] b);
一次最多读取b.length个字节
减少硬盘和内存的交互,提高程序的执行效率
*/
public class IOStreamTest02 {
public static void main(String[] args) throws FileNotFoundException {
//创建输入流对象
FileInputStream fis = null;
try {
fis = new FileInputStream("20201109/src/BUPT20201122/Java");
//IDEA工程Project目录的根就是默认当前路径
byte[] bytes = new byte[15];
//返回的是字节读的数量,不是字节本身
int readCount = fis.read(bytes);
//如果把这一块输出,那么会接着读,一直读到末尾,
//第一次返回整个byte数组的数量
//第二次就返回剩下没读完的一口气读完
//第三次就返回-1
//但是如果要给他转为String进行输出,那么第一次会读进去的15个都输出
//但第二次是把读到的4个覆盖数组中的前四个元素//
//后面的还是之前那15个里面的后11个
//这并不是我们期待的,应该是读多少个就转多少个
//因此要传一个起始位置和偏移量
System.out.println(readCount);
System.out.println(new String(bytes));
System.out.println(new String(bytes, 0, fis.read(bytes)));
System.out.println(fis.read(bytes));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
//关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这样还是不太完美,改为循环来完成
package BUPT20201122;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class IOStreamTest02 {
public static void main(String[] args) throws FileNotFoundException {
//创建输入流对象
FileInputStream fis = null;
try {
fis = new FileInputStream("20201109/src/BUPT20201122/Java");
byte[] bytes = new byte[15];
int readCount = 0;
//读多少转多少
while ((readCount = fis.read(bytes)) != -1) {
//注意这里不要换行,读到换行符自己会换行的
System.out.print(new String(bytes, 0, readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
//关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
两种常用的方法 skip和available
package BUPT20201122;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest01 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("20201109/src/BUPT20201122/Java");
//返回剩下没有读到的字节数量
/*
System.out.println(fileInputStream.available());
//有多少要读,直接一步到位,不用写循环,这种方式不太适合大文件
byte[] bytes = new byte[fileInputStream.available()];
int readCount = fileInputStream.read(bytes);
System.out.println(new String(bytes));
*/
//skip方法,跳过几个字节不读取
fileInputStream.skip(3);
System.out.println(fileInputStream.read());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
//关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileOutputStream
package BUPT20201122;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest01 {
public static void main(String[] args) throws FileNotFoundException {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream("Jindaohei.txt", true);
//写完之后一定要记得刷新
byte[] bytes = {97, 101, 110, 113};
//写入了文件里,没有文件就自动新建,有的话就清空再写
// 但如果在FileOutputStream中append参数为true,则表示追加
fileOutputStream.write(bytes);
fileOutputStream.write(bytes, 0, 2);
String s = "这是一段字符串";
//转一下类型
byte[] bytes1 = s.getBytes();
fileOutputStream.write(bytes1);
fileOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
文件的复制
package BUPT20201129;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
使用FileInputStream和FileOutputStream完成文件的拷贝
一边读,一边写,使用字节流,什么类型文件都能拷
*/
public class Copy01Test {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
//创建输入流对象
fileInputStream = new FileInputStream("E:\\研一\\4_20201019_光纤的损耗、色散、光的调制.mp4");
//创建输出流对象
fileOutputStream = new FileOutputStream("D:\\4_20201019_光纤的损耗、色散、光的调制.mp4");
//一边读,一边写,一次拷贝1MB
byte[] bytes = new byte[1024 * 1024];
int readCount = 0;
//读多少写多少
while ((readCount = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, readCount);
}
//记得刷新
fileOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//分开用try,不然可能影响到另一个的关闭
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader
package BUPT20201129;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
FileReader读取文本的字符输入流
*/
public class FileReaderTest {
public static void main(String[] args) {
FileReader fileReader = null;
try {
fileReader = new FileReader("Java代码.txt");
//一次读四个char
char[] chars = new char[4];
int readCount = 0;
while ((readCount = fileReader.read(chars)) != -1) {
System.out.print(new String(chars, 0, readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWriter
package BUPT20201129;
import java.io.FileWriter;
import java.io.IOException;
/*
FileWriter文件字符输出流,只能输出普通文本
*/
public class FileWriterTest {
public static void main(String[] args) {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("Java代码.txt", true);
char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
fileWriter.write(chars);
fileWriter.write(chars, 2, 3);
fileWriter.write("你好");
fileWriter.write("\n这里换行了");
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter != null)
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader和FileWriter完成复制粘贴
package BUPT20201129;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
FileRead/FileWriter执行拷贝普通文本文件
*/
public class Copy02 {
public static void main(String[] args) {
FileReader in = null;
FileWriter out = null;
try {
in = new FileReader("Java代码.txt");
out = new FileWriter("Java代码2.txt");
//一个char两个bit,这里就是一兆
char[] chars = new char[1024 * 512];
int readCount = 0;
while ((readCount = in.read(chars)) != -1) {
out.write(chars, 0, readCount);
}
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
带缓冲区的流
BufferedReader
package BUPT20201130;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("F:\\编程学习\\Java学习\\学习啊.txt");
//传参直接传的是reader,但reader是一个抽象类,FileReader是他的子类
//当一个流的参数为流时,被传进来的流称为节点流,外部负责包装的叫包装流(处理流)
BufferedReader bufferedReader = new BufferedReader(fileReader);
//读取一行
String FirstLine = bufferedReader.readLine();
System.out.println(FirstLine);
//关闭只需要关包装流就行
String s = null;
//读的一行不包括换行符
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
}
bufferedReader.close();
}
}
节点流和包装流
package BUPT20201130;
import java.io.*;
public class BufferedReadTest02 {
public static void main(String[] args) throws IOException {
//字节流
FileInputStream fileInputStream = new FileInputStream("F:\\编程学习\\Java学习\\学习啊.txt");
//字节流转为字符流
InputStreamReader reader = new InputStreamReader(fileInputStream);
//一次只能传一个字符流
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
}
package BUPT20201130;
import java.io.*;
/*
BufferedWriter:带有缓冲的字符输出流
OutPutStreamWriter:转换流
*/
public class BufferedWriterTest01 {
public static void main(String[] args) throws IOException {
//写一个新的文本文件
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("F:\\编程学习\\Java学习\\学习啊2.txt"));
//字节变字符,再传参
BufferedWriter bufferedWriter1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("F:\\编程学习\\Java学习\\学习啊3.txt")));
bufferedWriter.write("hello Java\n");
bufferedWriter.write("This is a Java Program");
bufferedWriter1.write("hello Java\n");
bufferedWriter1.write("This is a Java Programming");
bufferedWriter1.flush();
bufferedWriter1.close();
bufferedWriter.flush();
bufferedWriter.close();
}
}
结束时间:2020-11-30