【字节流】
OutputStream() 所有字节输出流的超类
| --- FileOutputStream
| --- BufferedOutputStream 字节输出流缓冲流
InputStream() 所有字节输入流的超类
| --- FileInputStream
| --- BufferedInputStream 字节输入流缓冲流
【开发常用的编码表】 GBK 、UTF-8 、ISO-8859-1
【编码和解码】
把字符转为字节: 编码 。"abc".getBytes() byte[]
把字节转为字符: 解码。 byte[] ={97,98,99} new String(b)
如果编码解码的过程中使用了不同的编码方式,就会出现乱码现象。
GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节。
UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节。
String str1 = "中文";
byte[] bytes = str1.getBytes("UTF-8");
String str2 = new String(bytes, "UTF-8");
System.out.println(str2);
【字节输出流OutputStream】抽象类
/*
* OutputStream(抽象类)
* 字节输出流: java.io.OutputStream 所有字节输出流的超类
* 作用:从java程序,写出文件
* 字节:每次只操作文件中一个字节,可以写任意文件
*
* write(int b) 将指定的字节写入输出流
* write(byte[] b) 写将b.length个字节从指定的byte数组中写入输出流
* write(byte[],int off , int len) 将指定byte数组中从偏移量off开始的len个字节写入次输出流
* close() 关闭此输出流,并释放与之有关的所有系统资源
*
* 注意:流对象操作文件时,自己不做,所有操作依赖于系统资源
*/
【FileOutputStream类】文件写入、续写、换行
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* A. FileoutputStream 写入数据文件
* 构造方法: 参数(File 封装文件) (String 字符串的文件名)
*
* 流对象使用步骤:
* 1. 创建流子类的对象,绑定数据目的
* 2. 调用流对象的方法write写
* 3. 释放资源close
*
* 注意:流对象的构造方法,可以创建文件,如果文件存在直接覆盖
*
* B. 文件的续写和换行
*/
public class FileOutputStreamDemo1 {
public static void main(String[] args) throws IOException {
function_2();
}
//A. 写入数据
public static void function_1() throws IOException{
FileOutputStream fos = new FileOutputStream("E:\\workspace\\Demo\\ab.txt");
// 流对象的方法write写数据 写入一个字节
// 1. 写入文件是字母 d
fos.write(100);
// 写入100
fos.write(49);
fos.write(48);
fos.write(48);
// 2. 写字节数组 a b c d
byte[] bytes = {97,98,99,100};
fos.write(bytes);
// 写字节数组额一部分 a b
fos.write(bytes,0,2);
// 写入字节数组的简便方式 写入"Hello World" ,getBytes()将字符串转为字节
fos.write(" Hello World".getBytes());
// 关闭资源
fos.close();
}
//B. 文件的续写和换行
// 1. 续写:在FileOutputStream构造方法的第二个参数加入 true
// 2. 换行:写入换行,符号换行 \r\n 可以写在上一行的末尾 或 下一行的开头
public static void function_2() throws IOException{
File file = new File("E:\\workspace\\Demo\\ab1.txt");
FileOutputStream fos = new FileOutputStream(file,true);
fos.write("Hello\r\n".getBytes());
fos.write("World".getBytes());
fos.close();
}
/* 打印输出:
Hello
World
*/
}
【IO中的异常处理】
import java.io.FileOutputStream;
import java.io.IOException;
/*
* IO流的异常处理 try catch finally
*/
public class FileOutputStreamIOEDemo1 {
public static void main(String[] args) {
// 1.保证流对象 fos 变量 作用域足够
FileOutputStream fos = null;
// try 外边声明变量,try内建立对象
try{
fos = new FileOutputStream("E:\\workspace\\Demo\\ab2.txt");
fos.write(100);
}catch(IOException ex){
System.out.println(ex.getMessage());
throw new RuntimeException("文件写入失败,重试");
}finally{
try{
//2. 若创建流对象失败,即fos==null,不需要close
if(fos != null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("关闭资源失败");
}
}
}
}
【字节输入流InputStream】超类
/*
* InputStream 所有字节输入流的超类
* 作用:读取任意文件,每次只读取一个字节
* 读取方法:
* int read() 读取一个字节
* int read(byte[] b) 读取一定量的字节,存储到数组中
*/
【字节输入流FileInputStream】
import java.io.FileInputStream;
import java.io.IOException;
/*
* FileInputStream 读取文件
* 构造方法:为这个流对象绑定数据源
* 参数(File 类型对象) (String 对象)
*
* 输入流读取文件的步骤:
* 1. 创建字节输入流的子类对象
* 2. 调用读取方法read 读取
* 3. 关闭资源
*
* read()方法,read()执行一次,就会自动读取下一字节
* 返回的是读取到的字节,读取到结尾后返回 -1
*/
public class FileInputDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("E:\\workspace\\Demo\\ab.txt"); // 文件中元素为ABC
// 使用循环方法读取文件一个字节,循环结束条件read()方法返回 -1
int len = 0;
while((len=fos.read()) != -1){
//System.out.println(len); // 65 66 67
System.out.print((char)len); // A B C
}
/* 注意
while(fos.read() != -1){
System.out.println(fos.read()); // 66 -1
}
*/
/*
// 获取一个字节,调用方法read,返回int
int i = fos.read();
System.out.println(i); // 获取的是65 但真实文件中是 A
i = fos.read();
System.out.println(i); // 获取的是66 但真实文件中是 B
i = fos.read();
System.out.println(i); // 获取的是67 但真实文件中是 C
i = fos.read();
System.out.println(i); // 文件中没有元素,返回 -1
*/
// 关闭资源
fos.close();
}
}
import java.io.FileInputStream;
import java.io.IOException;
/*
* FileInputStream 读取文件
* 读取方法 int read(byte[] b)
* 参数:数组b起缓冲作用,提高效率
* 返回值int: 表示读取到多少个有效的字节数
*/
public class FileInputDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("E:\\workspace\\Demo\\ab.txt"); // 文件中元素为ABCDE
// 创建字节数组
byte[] b = new byte[2];
int len = 0;
// 使用循环读取一个文件
while((len = fos.read(b)) != -1){
System.out.print(new String(b,0,len)); // ABCDE
}
// 关闭资源
fos.close();
}
}
/*
int len = fos.read(b);
System.out.println( new String(b)); // AB
System.out.println(len); // 2
len = fos.read(b);
System.out.println(new String(b)); // CD
System.out.println(len); // 2
len = fos.read(b);
System.out.println(new String(b)); // E
System.out.println(len); //
len = fos.read(b);
System.out.println(new String(b)); // E
System.out.println(len); //
*/
【字节流复制文件】效率最快的方法
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 将数据源:E:\\workspace\\Demo\\a\\jdk+api+1.8_China.zip
* 复制到:E:\\workspace\\Demo\\b\\jdk+api+1.8_China.zip
*/
public class Copy {
public static void main(String[] args) {
// 定义两个流对象变量
FileInputStream fis = null;
FileOutputStream fos = null;
try{
// 建立2个流对象,绑定数据源 和 数据目的
fis = new FileInputStream("E:\\workspace\\Demo\\a\\jdk+api+1.8_China.zip");
fos = new FileOutputStream("E:\\workspace\\Demo\\b\\jdk+api+1.8_China.zip");
// 采用数组缓存提高效率
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件复制失败");
}finally{
try{
if(fos != null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("资源释放失败");
}finally{
try{
if(fis != null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("资源释放失败");
}
}
}
}
}