Java SE自学笔记Real_009(IO流基础)
一、基础原理
java IO原理:
I/O是input/output的缩写,I/O技术是非常使用的技术,用于处理设备之间的数据传输
java程序中,对于数据的输入与输出操作以“流(stream)”的方式进行
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据
二、分类
按照数据单位不同:字节流(8bit) 字符流(16bit char)
按数据的流向不同:输入流,输出流
按流的角色不同:节点流(直接作用于输入输出端口),处理流(在节点流外面包着的其他流,用于处理节点流)
最根部的四个类(四个基本的抽象基类)
抽象类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
三、FileReader
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
一、流的分类:
1、操作数据单位:字节流、字符流
2、数据的流行:输入流、输出流
3、流的角色:节点流、处理流
二、流的体系结构
四个抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
InputStream FileInputStream BufferInputStream
OutputStream FileOutputStream BufferOutputStream
Reader FileReader BufferReader
Writer FileWriter BufferWriter
*/
public class FileReaderWriterTest {
public static void main(String[] args){
//==============添加trycatch语句:CTRL+alt+t===============================
FileReader fr = null;
try{
//1、实例化File类的对象,知名要操作的文件
File file = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\IOStudy\\src\\com\\IOLearning\\Demo001\\hello.txt"); //相较于当前的工程
//System.out.println(file.getAbsolutePath());
//2、提供具体的流
fr = new FileReader(file);
//3、数据的流入
//read():返回读入的一个字符,如果到达末尾,则返回-1
//异常的处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally处理
int data = fr.read();
while(data != -1){
System.out.print((char)data);
data = fr.read();
}
}catch(IOException e){
e.printStackTrace();
}
try {
//4、流的关闭操作
if(fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//对read()操作升级,使用read的重载方法
public class FileReaderTest2 {
public static void main(String[] args) {
FileReader fr = null;
try {
//1、File类的实例化
File file = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\IOStudy\\src\\com\\IOLearning\\Demo001\\hello.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 < len; i++){
System.out.print(cbuf[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fr != null){
try {
//4、资源的关闭
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四、FileWriter
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/*
从内存中写出数据到硬盘的文件里
说明:
1、输出操作,对应的File可以不存在,会自动创建该文件
2、如果存在,如果使用的流是FileWriter(file, false) 或者FileWriter(file)那么就会覆盖原本来文件
如果使用的是FileWriter(File, true)那么就是在原来的文件中进行追加内容
*/
public class FileWriterTest1 {
public static void main(String[] args) throws IOException {
//1、提供File类的对象,知名写出到的文件
File file = new File("hello1.txt");
//2、提供FileWriter的对象,用于数据的写出
FileWriter fw = new FileWriter(file, false);
//3、写出的操作
fw.write("I have a dream\n");
fw.write("You too");
//4、流资源的关闭
fw.close();
}
}
对文件进行读入和写出的连续操作
import java.io.*;
//对文件进行读入和写出操作
public class FileWriterTest2 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
//1、创建File类的对象,并指明读入和写出的文件
File srcFile = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\IOStudy\\src\\com\\IOLearning\\Demo001\\hello.txt");
File destFile = new File("hello2.txt");
//2、创建两个对象FileReader和FileWriter
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//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、流资源的关闭
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
不能使用字符流对象进行图片等字节流的操作!!
五、FileInputStream和FileOutputStream
1、处理文本文件
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/*
1、对于文本文件,用字符流进行处理(.txt .java .c .cpp)
2、对于非文本文件,用字节流进行处理(.jpg .mp3 .mp4 .avi .doc .ppt)
*/
//FileInputStream不能用来读中文,因为是字节流,而汉字是用三个字节来存储的,但是可以正常地读英文
public class FileInputStreamTest1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
File file = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\IOStudy\\src\\com\\IOLearning\\Demo001\\hello.txt");
fis = new FileInputStream(file);
byte[] buffer = new byte[5];
int len;
while((len = fis.read(buffer)) != -1){
String str = new String(buffer, 0, len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、处理非文本文件
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FIleInputStreamTest2 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1、创建file类地对象,在笔名要操作的文件
File srcFile = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\bg.png");
File destFile = new File("bg1.png");
//2、创建FileInputStream类的对象
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//3、读入的操作
byte[] buffer = new byte[5];
int len; //每次接收字节的长度
while((len = fis.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、流资源的关闭
try {
if(fis != null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fos != null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
六、缓冲流:BufferedInputStream和BufferOutputStream
import java.io.*;
/*
处理流之一:缓冲流的使用
1、缓冲流:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferWriter
2、作用:提高流的读取,写入的速度
*/
public class BufferFeredTest1 {
public static void main(String[] args){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1、造文件
File srcFile = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\bg.png");
File destFile = new File("bg2.png");
//2、造流
//2.1、造字节流
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//2.2、造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3、复制的细节:读取、写入
byte[] buffer = new byte[1024];
int len;
while((len = bis.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、关闭资源
//要求:先关闭外层的资源,在关闭里层的资源(先关闭缓冲流,再关闭字节流)
try {
if(bos != null) bos.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bis != null) bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//说明:再关闭外层流的同时,内层流也会自动关闭,所以内层流的关闭可以省略
//fos.close();
//fis.close();
}
}
}
七、缓冲流:BufferedReader和BufferWriter
import java.io.*;
//字符型缓冲流测试:使用BufferedReader和BufferWriter对文本文件进行复制
public class BufferedReaderTest1 {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
//1、File类的实例化
File srcFile = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\IOStudy\\src\\com\\IOLearning\\Demo001\\hello.txt");
File destFile = new File("hello4.txt");
//2、FileReader和FileWriter实例化
FileReader fr = new FileReader(srcFile);
FileWriter fw = new FileWriter(destFile);
br = new BufferedReader(fr);
bw = new BufferedWriter(fw);
//3、操作的细节
/*
//方式一:利用字符数组进行读取
char[] cbuf = new char[1024];
int len;
while((len = br.read(cbuf)) != -1){
bw.write(cbuf, 0, len);
bw.flush();
}
*/
//方式二:利用String
String data;
while((data = br.readLine()) != null){
bw.write(data + "\n"); //打他中 不包含换行符
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、关闭资源
try {
if(bw != null) bw.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bw != null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
小练习:将图片进行加密操作
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//对图片及逆行加密操作
public class Exercise1 {
public static void main(String[] args) {
//图片的加密操作
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\bg.png");
fos = new FileOutputStream("bg3.png");
byte[] buffer = new byte[20];
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);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
八、转换流
InputStreamReader
/*
处理流二:转换流的使用
1、转换流:属于字节流
InputStreamReader:将一个字节的输入流转换为字符的输入流
OutputStreamWriter:将一个字符的输出流转换为字节的输出流
2、作用:提供字节流与字符流之间的转换
3、解码:字节、字节数组--->字符数组,字符串
编码:字符数组,字符串--->字节、字节数组
*/
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderTest {
public static void main(String[] args){
InputStreamReader isr = null; //第二个参数不设置就是系统默认的字符集,UTF-8
try {
FileInputStream fis = new FileInputStream("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\hello4.txt");
//参数2:指明了字符集,
isr = new InputStreamReader(fis, "UTF-8");
char[] cbuf = new char[20];
int len;
while((len = isr.read(cbuf)) != -1){
String str = new String(cbuf, 0, len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(isr != null){isr.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
OutputStreamWriter
import java.io.*;
//利用OutputStreamWriter将hello4.txt文件转换为gbk形式进行写出保存
public class OutputStreamWriterTest {
public static void main(String[] args) {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
File file1 = new File("D:\\NewSoftwares\\Javasooftware\\javaprojects\\JavaSE008\\hello4.txt");
File file2 = new File("hello5_gbk.txt");
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
isr = new InputStreamReader(fis, "UTF-8");
osw = new OutputStreamWriter(fos, "gbk");
char[] cbuf = new char[20];
int len;
while((len = isr.read(cbuf)) != -1){
osw.write(cbuf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(isr != null) isr.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(osw != null) osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
九、字符集(编码)
ASSCII:美国标准信息交换码
用一个字节的7为可以表示(一个字节有8位)
ISO8859-1:拉丁码表,欧洲码表
用一个字节的8位表示
GB2312:中国的中文编码表,最多两个字节编码所有字符
GBK:中国的中文编码升级,融合了更多死亡中文文字字符,最多两个字节编码
Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配一个唯一的字符码,所有的文字都用两个字节来表示
面向传输的众多UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8就是每次进项8个位传输数据,UTF-16就是每次16个位传输数据,这是位传输而设计的编码,并使得编码无国界,这样就可以显示全世界上所欲文化的字。