流的分类
按操作数据单位不同分为:字节流(8bit)、字符流(16bit)
按数据流的流向不同分为:输入流、输出流
按流的角色的不同分为:节点流、处理流
流的体系结构
抽象基类 | 节点流(或文件流) | 缓冲流(处理流的一种) |
---|---|---|
InputStream | FileInputStream (read(byte[] buffer)) | BufferedInputStream (read(byte[] buffer)) |
OutputStream | FileOutputStream (write(byte[] buffer,0, len)) | BufferedOutputStream (write(byte[] buffer, 0, len)) |
Reader | FileReader (read(char[] cbuf)) | BufferedReader (read(char[] cbuf)) |
Writer | FileWriter (write(char[] cbuf, 0, len)) | BufferedWriter (write(char[] cbuf, 0, len)) |
FileReader读入数据的基本操作
将Day09下的hello.txt文件内容读入程序中,并输出到控制台
package a01;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Test2 {
public static void main(String[] args){
FileReader fr = null;
try {
//1.实例化File类的对象,指明要操作的文件
File file = new File("Day01\\hello.txt");
System.out.println(file.getAbsoluteFile());
//2.提供具体的流
fr = new FileReader(file);
//3.数据的读入
//read():返回读入的一个字符。如果达到文件末尾,返回-1
int data = fr.read();
if (data!=-1){
System.out.println((char)data);
data = fr.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流的关闭操作
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
说明:
1.read()的理解,返回读入的一个字符。如果达到文件末尾,返回-1
2.异常的处理:为了保证流资源一定可以执行关闭操作,需要使用tey-catch-finally处理
3.读入的文件一定要存在,否则就会报FileNotFoundException
FileReader中使用read(char[] cbuf)读入数据
package a01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test3 {
public static void main(String[] args){
FileReader fr = null;
try {
//1.File类的实例化
File file = new File("hello1.txt");
//2.FileReader流的实例化
fr = new FileReader(file);
//3.读入的操作
char[] cbuf = new char[5];
int len;
while((len = fr.read(cbuf))!=-1){
//方式一:
//错误写法:
// for (int i = 0; i < cbuf.length; i++) {
// System.out.println(cbuf[i]);
// }
//正确写法:
for (int i = 0; i < len; i++) {
System.out.println(cbuf[i]);
}
}
//方式二:
//错误写法:
// String str = new String(cbuf);
// System.out.print(str);
//正确写法:
String str = new String(cbuf,0,len);
System.out.print(str);
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源的关闭
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWrite()写出数据的操作
从内存中写出数据到硬盘的文件里
package a01;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Test2 {
public static void main(String[] args) throws IOException {
//1.实例化File类的对象,指明要操作的文件
File file = new File("Day01\\hello.txt");
System.out.println(file.getAbsoluteFile());
//2.提供具体的流
FileReader fr = new FileReader(file);
//3.数据的读入
//read():返回读入的一个字符。如果达到文件末尾,返回-1
int data = fr.read();
if (data!=-1){
System.out.println((char)data);
data = fr.read();
}
//4.流的关闭操作
fr.close();
}
}
说明:
1.输出操作,对应的File可以不存在的,并不会报异常
File对应的硬盘中的文件如果不存在,在输出过程中,会自动创建此文件
File对应的硬盘中的文件如果存在:
如果流使用的构造器是FileWriter(file,false) / FileWriter(file):对原有文件的覆盖
如果流使用的构造器是FileWriter(file,true):对原有文件的追加
使用FileReader和FileWriter实现文本文件的复制
package a01;
import java.io.*;
public class Test4 {
public static void main(String[] args){
FileReader fr = null;
FileWriter fw = null;
try {
//1.创建File文件实例化
File srcFile = new File("hello1.txt");
File descFile = new File("hello2.txt");
//2.创建FileReader和FileWriter实例化
fr = new FileReader(srcFile);
fw = new FileWriter(descFile);
//3.读入写出数据
char[] cbuf = new char[5];
int len;//记录每次读入到cbuf数组中的字符的个数
while ((len=fr.read(cbuf))!=-1){
//每次写出len个字符
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流资源
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字符流不能处理图片文件的处理
使用FileInputStream和FileOutputStream读写非文本文件
//实现对图片的复制操作
package com.yan;
import java.io.*;
public class FileInputOutputTest {
public static void main(String[] args){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File file1 = new File("Day01\\money.jpg");
File file2 = new File("Day01\\money2.jpg");
fis = new FileInputStream(file1);
fos = new FileOutputStream(file2);
byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
结论:
1.对于文本文件(.txt .java .c .cpp)使用字符流处理
2.对于非文本文件(.jpg .mp3 .mp4 .avi .doc .ppt……)使用字节流处理
使用FileInputStream和FileOutputStream复制非文本文件
package com.yan;
import java.io.*;
public class Test1 {
public static void copyFile(String srcPath, String descPath){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File srcFile = new File(srcPath);
File descFile = new File(descPath);
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(descFile);
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
String srcPath = "C:\\Users\\pon18\\Desktop\\01-视频.mp4";
String descPath = "C:\\Users\\pon18\\Desktop\\02-视频.mp4";
copyFile(srcPath,descPath);
}
}
缓冲流(字节型)实现非文本文件的复制
缓冲流的作用:提供流的读取、写入的速度
提高读写速度的原因:内部提供了一个缓冲区
package com.yan;
import java.io.*;
public class BufferedStreamTest {
public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.造文件
File srcFile = new File("Day01\\money.jpg");
File descFile = new File("Day01\\money1.jpg");
//2.造流
//2.1造节点流
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(descFile);
//2.2造处理流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3.复制操作
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流资源
//要求:先关闭外层的流,再关闭内层的流
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//说明:关闭外层流的同时,内层流也会自动的进行关闭,可以省略
// fos.close();
// fis.close();
}
}
}
缓冲流(字符型)实现文本文件的复制
package com.yan;
import java.io.*;
public class BufferedStreamTest1 {
public static void main(String[] args){
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("Day01\\hello.txt"));
bw = new BufferedWriter(new FileWriter("Day01\\hello1.txt"));
// //方式一:
// char[] cbuf = new char[10];
// int len;
// while((len = br.read(cbuf))!=-1){
// bw.write(cbuf,0,len);
// }
//方式二:
String data;
while((data = br.readLine())!=null){//到末尾即为空null
//方法一:
// bw.write(data);//data中不包含换行符
// bw.write(data+"\n");
//方法二:
bw.write(data);//data中不包含换行符
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
练习
//实现图片加密操作
package com.yan;
import java.io.*;
public class photoSecretTest {
public static void main(String[] args) throws IOException {
File srcFile = new File("Day01\\money.jpg");
File descFile = new File("Day01\\moneysecret.jpg");
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(descFile);
byte[] buffer = new byte[10];
int len;
while ((len = fis.read(buffer))!=-1){
for (int i = 0; i < len; i++) {
buffer[i] = (byte) (buffer[i] ^ 5);
}
fos.write(buffer,0,len);
}
fos.close();
fis.close();
}
}
//恢复图片操作
package com.yan;
import java.io.*;
public class photoTest {
public static void main(String[] args) throws IOException {
File srcFile = new File("Day01\\moneysecret.jpg");
File descFile = new File("Day01\\money3.jpg");
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(descFile);
byte[] buffer = new byte[10];
int len;
while ((len = fis.read(buffer))!=-1){
for (int i = 0; i < len; i++) {
buffer[i] = (byte) (buffer[i] ^ 5);
}
fos.write(buffer,0,len);
}
fos.close();
fis.close();
}
}
转换流
处理流之二:转换流的使用
1.转换流:属于字符流
InputStreamReader:将一个字节的输入流转换为字符的输出流
OutputStreamWriter:将一个字符的输出流转换为字节的输出流
2.作用:提供字节流和字符流之间的转换
3.解码:字节、字节数组————>字符数组、字符串
编码:字符数组、字符串————>字节、字节数组
4.字符集
输入流、输出流
1.1System.in:标准输入流,默认从键盘输入
System.out:标准输出流,默认从控制台输出
1.2
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流
1.3
使用Scanner实现,调用next()返回一个字符串
使用System.in实现。System.in ——>转换流——>BufferedReader的readLine()
打印流
PrintStream和PrintWriter
提供了一系列重载的print()和println()
数据流
DataInputStream和DataOutputstream
用来读取或写出基本数据类型的变量和字符串
注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序保持一致!