一、前言:
菜鸟一枚,利用假期学习Java基础知识,想以博客的方式记录自己学习过的知识。内容绝对有瑕疵,希望路过看到的大佬们多多指正,多多交流!菜鸟在此先谢为过!
二、预备知识:
1.ASCII码表描述的是:char和int之间的关系;
2.常见字符的码值:'0' — 48 、'A' — 65 、'a' — 97;
3.计算机最基本的存储单位是:字节;
4.在 GBK码表 中,一个中文占 2个 字节;在 UTF-8码表 中,一个中文占 3个 字节
5.数字,字母以及特殊符号,不管在什么码表中 均为占 1个 字节;
6.Eclipse默认编码表 默认是 GBK 码表
7.IO流的顶层 都是抽象类 集合的顶层都是接口
完整版ASCII码表如下图(应该不用记):
图片来源网络(还有水印)侵删!
三、概述:
I — Input O — Output 用来传输数据
四、分类:
1. 按流向分类:(输入流和输出流)
输入流:读取数据
输出流:写出数据
2.按操作分类:(字节流和字符流)
字节流:以字节为单位操作数据
字节输入流 最顶层抽象类:InputStream 子类:FileInputStream
子类构造方法:
public FileInputStream(String name);
public FileInputStream(File file);
字节输出流 最顶层抽象类:OutputStream 子类:FileOutputStream
子类构造方法:
public FileOutputStream(String name);
public FileOutputStream(String name,boolean append);
// 两个构造方法的详细介绍在后
字符流:以字符为单位操作数据
字符输入流 最顶层抽象类:Reader 子类:FileReader
子类构造方法:
public FileReader(String name);
public FileReader(File file);
字符输出流 最顶层抽象类:Writer 子类:FileWriter
子类构造方法:
public FileWriter(String fileName);
public FileWriter(String fileName,boolean append);
//两个构造方法的详细介绍在后
五、字节流构造方法:
//字节输入流构造方法
public static void fileInputStreamMethod() throws IOException {
// 创建 FileInputStream 对象
FileInputStream fileInputStream = new FileInputStream("F:\\Eclipse TestFile\\a.txt");
// 读取数据
int ch = 0; //用来记录读取到的内容
while ((ch = fileInputStream.read()) != -1) {
/*
* (ch = fileInputStream.read()) != -1 进行的三步操作
*
* 1.read();读取数据
* 2.读到的内容赋值给 ch
* 3. 将 ch 和 -1 进行比较
*/
System.out.println((char)ch);
}
//注意:所有的IO流的代码 最终别忘了关流
fileInputStream.close();
}
//字节输出流构造方法1
//方法实现的是:覆盖操作
public static void fileOutputSrtreammethod1() throws IOException {
// 创建FileOutputStream 对象
//如果文件不存在 即123.txt 不存在 会创建一个文件
FileOutputStream fileOutputStream = new FileOutputStream("123.txt");
// 往文件中写入数字
fileOutputStream.write(97);
// 关流
fileOutputStream.close();
}
//字节输出流构造方法2
//该方法实现的是:添加操作
public static void fileOutputStreamMethod2() throws IOException {
// 创建FileOutputStream 对象
// 如果文件不存在 即123.txt 不存在 会创建一个文件
FileOutputStream fileOutputStream = new FileOutputStream("123.txt", true);
//true 代表的是追加的意思
// 往文件中写入数据 97
fileOutputStream.write(97);
// 关流
fileOutputStream.close();
}
六、字符流构造方法:
关于字符流构造方法的应用,与字节流构造方法原理相同。
七、IO流核心代码步骤:
1.创建输入流对象,封装数据源文件
2.创建输出流对象,封装目的地文件
3.定义一个变量,用来记录读取到的字节(符)
4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给变量
5.将读取到的内容写入到目的地文件中
6.关闭IO流,释放资源
八、具体示例:
1.字节流一次读写一个字节
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class OneByOneBytesCopy {
public static void main(String[] args) throws IOException {
/*
* 需求:使用字节流将 F:\下的 1.jpg 拷贝 到 项目下名称不变
*
* IO流的核心代码:
* 1.创建输入流对象,封装数据源文件
* 2.创建输出流对象,封装目的地文件
* 3.定义一个变量,用来记录读取到的字节
* 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给变量
* 5.将读取到的内容写入到目的地文件中
* 6.关闭IO流,释放资源
*/
// 1.创建输入流对象,封装数据源文件
FileInputStream fileInputStream = new FileInputStream("F:\\1.jpg");
// 2.创建输出流对象,封装目的地文件
FileOutputStream fileOutputStream = new FileOutputStream("copy1.jpg");
// 3.定义一个变量,用来记录读取到的字节
int ch = 0;
// 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给变量
while ((ch = fileInputStream.read())!= -1) {
// 5.将读取到的内容写入到目的地文件中
fileOutputStream.write(ch);
}
// 6.关闭IO流,释放资源
fileInputStream.close();
fileOutputStream.close();
System.out.println("拷贝完成!");
}
}
2.字节流一次读写一个字节数组
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class OneByOneBytesArrayCopy {
public static void main(String[] args) throws IOException {
//字节流 一个读取一个指定长度的字节数组
/*
* 需求:使用字节流将 项目下的 11.txt 拷贝 到 项目下 名称 改为 copy11.txt
*
* IO流的核心代码:
* 1.创建输入流对象,封装数据源文件
* 2.创建输出流对象,封装目的地文件
* 3.定义一个变量,用来记录读取到的 有效字节数
* 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给 字节数组 中
* 将读取到的有效字节数赋值给变量
* 5.将读取到的内容写入到目的地文件中
* 6.关闭IO流,释放资源
*/
// 1.创建输入流对象,封装数据源文件
FileInputStream fileInputStream = new FileInputStream("11.txt");
// 2.创建输出流对象,封装目的地文件
FileOutputStream fileOutputStream = new FileOutputStream("copy11.txt");
// 3.定义一个变量,用来记录读取到的 有效字节数
byte[] bytes = new byte[3];
int length = 0;
// 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给 字节数组 中,将读取到的有效字节数赋值给变量
while ((length = fileInputStream.read(bytes))!= -1) {
/*
* public int read(byte[] bytes)
* 作用:一次读取一个指定长度的字节数组,将读取到的内容放到字节数组(bytes[])中
* 并返回读取到的有效字节数,读取不到返回 -1
* 对照 read(); 方法理解
*/
// 5.将读取到的内容写入到目的地文件中
fileOutputStream.write(bytes, 0, length);
}
// 6.关闭IO流,释放资源
fileInputStream.close();
fileOutputStream.close();
System.out.println("拷贝完成");
}
3.字符流一次读写一个字符
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class OneByOneCharCopy {
public static void main(String[] args) throws IOException {
/*
* IO流的核心代码:
* 1.创建输入流对象,封装数据源文件
* 2.创建输出流对象,封装目的地文件
* 3.定义一个变量,用来记录读取到的字符
* 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给变量
* 5.将读取到的内容写入到目的地文件中
* 6.关闭IO流,释放资源
*/
//需求:小说.txt --->copy小说.txt
// 1.创建输入流对象,封装数据源文件
FileReader fileReader = new FileReader("小说.txt");
// 2.创建输出流对象,封装目的地文件
FileWriter fileWriter = new FileWriter("copy小说.txt");
// 3.定义一个变量,用来记录读取到的字符
int ch = 0;
// 4.循环读取,只要条件满足就一直读取,并将读取到的内容记录给变量
while ((ch = fileReader.read())!=-1) {
// 5.将读取到的内容写入到目的地文件中
fileWriter.write(ch);
}
// 6.关闭IO流,释放资源
fileReader.close();
fileWriter.close();
System.out.println("拷贝完成");
}
}
4.字符流一次读写一个字符数组
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class OneByOneCharArrayCopy {
public static void main(String[] args) throws IOException {
/*
* IO流的核心代码:
* 1.创建输入流对象,封装数据源文件
* 2.创建输出流对象,封装目的地文件
* 3.定义一个变量,用来记录读取到的有效字符数
* 4.循环读取,只要条件满足就一直读取,将读取到的内容存入到字符数组中
* 并将读取到的有效字符数赋值给变量
* 5.将读取到的内容写入到目的地文件中
* 6.关闭IO流,释放资源
*/
//需求:小说.txt --->copy小说.txt
// 1.
FileReader fileReader = new FileReader("小说.txt");
// 2.
FileWriter fileWriter = new FileWriter("copy小说.txt");
// 3.
char[] chars = new char[1024];
//1G = 1024 MB 1MB = 1024 KB 1KB = 1024 B
int length = 0 ;
// 4.
while ((length = fileReader.read(chars))!=-1) {
// 5.
fileWriter.write(chars, 0, length);
}
// 6.
fileReader.close();
fileWriter.close();
System.out.println("OK");
}
}
九、补充:高效的字节(符)流和转换流
1.高效的字符流示例
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class ApplyEfficientTest {
public static void main(String[] args) throws IOException {
//高效字符流:一次读一行!
//需求:把 帐号库.txt 复制到 copy帐号库.txt(帐号库.txt 如下图所示)
/*
* IO流的核心代码:
* 1.创建输入流对象,封装数据源文件
* 2.创建输出流对象,封装目的地文件
* 3.定义一个变量,用来记录读取到的字符串
* 4.循环读取,只要条件满足就一直读取,并将读取到的内容赋值给变量
* 5.将读取到的内容写入到目的地文件中
* 6.关闭IO流,释放资源
*/
//1.
FileReader fileReader = new FileReader("帐号库.txt");
//高效字符输入流(缓冲流),实现了一次读取一行的操作
BufferedReader bufferedReader = new BufferedReader(fileReader);
//2.
FileWriter fileWriter = new FileWriter("copy帐号库.txt");
//高效字符输出流,实现了一次写一行数据的操作
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
//3.
String lineString = "";
//4.
while ((lineString = bufferedReader.readLine())!= null) {
//5.
bufferedWriter.write(lineString);
//实现的是输出流文件的换行操作,但各个操作系统实现换行的代码不一样,故不推荐
// bufferedWriter.write("\r\n");
//根据操作系统,给出对应的换行符
bufferedWriter.newLine();
}
//6.
bufferedReader.close();
bufferedWriter.close();
System.out.println("高效的解决了!");
}
}
2.转换流示例
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransforStream_按指定码表读写文件 {
public static void main(String[] args) throws IOException {
//按照指定码表转换
CharsetNameTest();
//关于转换流的工作原理(见包下的图片)
/*
* InputStreamReader 是 字节流 通向 字符流 的桥梁
*
* OutputStreamWriter 是 字符流 通向 字节流 的桥梁
*/
}
public static void CharsetNameTest() throws IOException {
/*
* 将 UTF-8.txt(UTF-8编码格式)文件中的内容复制到GBK.txt(GBK码表编码)文件中
*
* 可以使用转换流来解决这个问题
* InputStreamReader(InputStream in,String charsetName)
* charsetName 规定输入流文件的码表
* OutputStreamWriter(OutputStream out,String charsetName)
* charsetName 规定输出流文件的码表
* 而且 charsetName 码表名 大小写不限制
*
* 注意:
* UTF-8码表中,一个中文占3个字符
* GBK码表中,一个中文占2个字符
*/
//1.创建输入流对象,封装数据源文件
FileInputStream fisFileInputStream = new FileInputStream("UTF-8.txt");
InputStreamReader isrInputStreamReader = new InputStreamReader(fisFileInputStream,"utf-8");
//2.创建输出流文件,封装目的地文件
OutputStreamWriter oswOutputStreamWriter = new OutputStreamWriter(new FileOutputStream("TestGBK.txt"),"gbk");
//3.定义变量,用来记录读取到的有效字符数
char[] chars = new char[1024];
int length = 0;
//4.循环读取文件,只要条件满足就一直循环,并将读取到的有效字符数赋值给变量
while ((length = isrInputStreamReader.read(chars))!= -1) {
//5.将读取到的内容写入到文件中
oswOutputStreamWriter.write(chars, 0, length);
}
//6.关流,释放资源
isrInputStreamReader.close();
oswOutputStreamWriter.close();
System.out.println("拷贝完成");
}
}
3.转换流的工作原理:
InputStreamReader 是字节流通向字符流的桥梁;OutputStreamWriter 是字符流通向字节流的桥梁。详细应用如下:
十、总结:
1.字节流与字符流的应用
字节流:
字节流可以操作任意类型的文件,但是操作中文文件时,有可能会出现乱码情况
记忆:
常用拷贝图片,音频或者视频
字符流:
专门用来操作中文文件
记忆:
当一个文件能用微软自带的记事本打开,并且里边内容能看懂时,就可以考虑用字符流处理
2.拷贝文件方式:
1)普通的字节流一次读写一个字节 FileInputStream#read( )
FileOutputStream#read( )
*2)普通的字节流一次读写一个字节数组 FileInputStream#read(byte bytes[ ])
FileOutputStream#write(byte b, int off,int len)
3)高效的字节流一次读写一个字节 BufferedInputStream#read( byte bytes[ ] )
BufferedOutputStream#write( byte b, int off,int len )
4)高效的字节流一次读写一个字节数组 BufferedInputStream#read( )
BufferedOutputStream#write( )
5)普通的字符流一次读写一个字符 FileReader#read( )
FileWriter#write( )
*6)普通的字符流一次读写一个字符数组 FileReader#read( char chars[ ] )
FileWriter#write( char c, int off,int len )
7)高效的字符流一次读写一个字符 BufferedFileReader#read( )
BufferedFileWriter#write( )
8)高效的字符流一次读写一个字符数组 BufferedFileReader#read( char chars[ ] )
BufferedFileWriter#write( char c, int off,int len )
*9)高效的字符流一次读写一行
BufferedReader#readLine( ); 一次读一行
BufferedWriter#write( String line ); 一次写一行
BufferedWriter#newLine( ); 根据当前系统,给出对应换行代码