目录

  • 一切皆为字节
  • 大纲
  • 图解大纲
  • 字节流读取文件
  • 读文件(未使用缓冲对)
  • FileInputStream
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 写文件(未使用缓冲对)
  • FileOutputStream
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 引入缓冲对的原因
  • 读文件(使用缓冲对)
  • BufferedInputStream
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 写文件(使用缓冲对)
  • BufferedOutputStream
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 字符流读取文件
  • 读文件(未使用缓冲对)
  • FileReader
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 写文件(未使用缓冲对)
  • FileWriter
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 读文件(使用缓冲对)
  • BufferedReader
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 写文件(使用缓冲对)
  • BufferedWriter
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 通往字符流--->字节流桥梁(解决不同编码格式可正常读取)
  • 读文件
  • InputStreamReader
  • 创建方法
  • 常用方法
  • 使用步骤
  • 注意事项
  • 样例
  • 写文件
  • OutputStreamWriter
  • 创建方法
  • 常用方法
  • 使用步骤
  • 样例
  • 综合案例
  • 复制图片格式文件
  • 注意事项


一切皆为字节

  我们可以右键查看我们的每一个文件的属性,在常规那一栏,你会发现无论是什么文件他在硬盘的存储形式都是以字节形式存储。

大纲

  因此java就提供了一种以字节流读取文件的类,但是,如果以字节流进行读取文件,对于不同的编码格式组成的字节是不一样的,容易出现乱码情况。比如:GBK编码和UTF-8编码,对于中文的编码一个是两个字节另外一个是三个字节。众所周知,对于所有的文字,英语字母都是以字符组成,因此在字节流的基础之上,java也提供了以字符流进行读取文件的方法。但这只是解决了基础的以字符解决,还没有满足到GBK和UTF-8编码格式之间的互转,因此java后面又推出了建立字符和字节之间的桥梁,可以通过他进行编码格式的转换。

图解大纲

java读取文件转为字节流 java高效读取文件字节流_java读取文件转为字节流

字节流读取文件

读文件(未使用缓冲对)

FileInputStream

创建方法

方法

概述

FileInputStream(File file)

通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名

FileInputStream(String name)

通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名

常用方法

返回值

方法

概述

int

read()

从该输入流读取一个字节的数据

int

read(byte[] b)

从该输入流读取最多 b.length个字节的数据为字节数组

void

close()

关闭此文件输入流并释放与流相关联的任何系统资源

使用步骤
  1. 创建fileinputstream对象
  2. 接收数据
  3. 读完数据。关闭对象,释放资源
样例
package fileReadAndWrite;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建fileinputstream对象
		// 你是要传入 File对象还是直接路径。如果路径找不到,会抛出文件无法找到异常
		FileInputStream inputStream = new FileInputStream("C:\\aaa\\a.txt");
		
		// 2. 接收数据
		// 可以用一个int类型数据。判断文件是否还有数据。如果返回 -1 说明读取结束
		// 为了提高效率可使用字节数组。当然也可以使用一个字节一个字节读取。但是效率慢
		int len ;
		byte[] bytes = new byte[1024];
		while((len = inputStream.read(bytes)) != -1) {
			System.out.println(new String(bytes,0,len));
		}
		
		// 3. 读完数据。关闭对象,释放资源
		inputStream.close();
	}

}

写文件(未使用缓冲对)

FileOutputStream

创建方法

方法

概述

FileOutputStream(File file)

创建文件输出流以写入由指定的 File对象表示的文件

FileOutputStream(File file, boolean append)

第二参数可设置是否追加写入

FileOutputStream(String name)

创建文件输出流以指定的名称写入文件

FileOutputStream(String name, boolean append)

第二参数可设置是否追加写入

常用方法

返回值

方法

概述

void

write(int b)

将指定的字节写入此文件输出流

void

write(byte[] b)

将 b.length个字节从指定的字节数组写入此文件输出流

void

write(byte[] b, int off, int len)

将 len字节从位于偏移量 off的指定字节数组写入此文件输出流

void

close()

关闭此文件输出流并释放与此流相关联的任何系统资源

使用步骤
  1. 创建fileoutputstream对象
  2. 开始向该路径写东西
  3. 写完数据。关闭对象,释放资源
样例
package fileReadAndWrite;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建fileoutputstream对象
		// 第一个参数可以选择:你是要传入 File对象还是直接路径。如果路径找不到,会抛出文件无法找到异常
		// 第二个参数可以选择:你是否要进行追加
		FileOutputStream outputStream = new FileOutputStream("C:\\aaa\\a.txt",true);
		
		// 2. 开始向该路径写东西
		// 可以选择 单个字节、字节数组
		outputStream.write(97);
		
		byte[] bytes = {97,98,99};
		// 对于 换行。也有一定的要求格式.注意将:字符串修改成字节数组就行了
		// windows:\r\n
		// linux: /n
		// mac : /r
		outputStream.write("\r\n".getBytes());
		outputStream.write(bytes);
		
		// 3. 写完数据。记得关闭,释放资源
		outputStream.close();
		
	}

}

引入缓冲对的原因

  1. 为了进一步缓和CPU和I/O设备之间速度不匹配的矛盾。
  2. 加快输入输出速度
  3. 提高CPU和I/O设备之间的并行性

读文件(使用缓冲对)

BufferedInputStream

创建方法

方法

概述

BufferedInputStream(InputStream in)

创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用

BufferedInputStream(InputStream in, int size)

创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用

常用方法

返回值

方法

概述

int

read()

从该输入流读取一个字节的数据

int

read(byte[] b)

从该输入流读取最多 b.length个字节的数据为字节数组

void

close()

关闭此文件输入流并释放与流相关联的任何系统资源

使用步骤
  1. 创建BufferedInputStream对象,传入一个fileinputstream对象
  2. 接受数据
  3. 读完数据。关闭对象,释放资源
样例
package fileReadAndWrite;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建BufferedInputStream对象
		// 传入一个fileinputstream对象
		BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("C:\\aaa\\a.txt"));
		
		// 2. 接受数据
		// 可以用一个int类型数据。判断文件是否还有数据。如果返回 -1 说明读取结束
		// 为了提高效率可使用字节数组。当然也可以使用一个字节一个字节读取。但是效率慢
		int len ;
		byte[] bytes = new byte[1024];
		while((len = inputStream.read(bytes)) != -1) {
			System.out.println(new String(bytes,0,len));
		}
		
		// 3. 读完数据。关闭对象,释放资源
		inputStream.close();

	}

}

写文件(使用缓冲对)

BufferedOutputStream

创建方法

方法

概述

BufferedOutputStream(OutputStream out)

创建一个新的缓冲输出流,以将数据写入指定的底层输出流

BufferedOutputStream(OutputStream out, int size)

创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流

常用方法

返回值

方法

概述

void

write(int b)

将指定的字节写入此文件输出流

void

write(byte[] b)

将 b.length个字节从指定的字节数组写入此文件输出流

void

write(byte[] b, int off, int len)

从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流

void

close()

关闭此文件输出流并释放与此流相关联的任何系统资源

void

flush()

刷新缓冲输出流

使用步骤
  1. 创建BufferedOutputStream对象,传入一个fileoutputstream对象
  2. 使用write写入数据
  3. 刷新缓冲对里面的数据
  4. 读完数据。关闭对象,释放资源。也会自动刷新缓冲对数据,因此第三步可省略
样例
package fileReadAndWrite;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		// 1. 创建BufferedOutputStream对象
		// 第一个参数可以选择:传入fileoutputstream对象---》  可以设置是否需要追加
		BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("C:\\aaa\\a.txt",true));
		
		// 2. 开始向该路径写东西
		// 可以选择 单个字节、字节数组
		outputStream.write(97);
		
		byte[] bytes = {97,98,99};
		// 对于 换行。也有一定的要求格式.注意将:字符串修改成字节数组就行了
		// windows:\r\n
		// linux: /n
		// mac : /r
		outputStream.write("\r\n".getBytes());
		outputStream.write(bytes);
		outputStream.write("你好".getBytes());
		
		// 3. 刷新缓冲对的数据
		outputStream.flush();
		
		// 4. 写完数据。记得关闭,释放资源。
		// 关闭的时候,会自动执行第三步
		outputStream.close();

	}

}

字符流读取文件

读文件(未使用缓冲对)

FileReader

创建方法

方法

概述

FileReader(File file)

创建一个新的 FileReader ,给出 File读取

FileReader(String fileName)

创建一个新的 FileReader ,给定要读取的文件的名称

常用方法

返回值

方法

概述

int

read()

读一个字符

int

read(char[] cbuf)

从该输入流读取最多 cbuf.length个字符

void

close()

关闭此文件输入流并释放与流相关联的任何系统资源

使用步骤
  1. 创建FileReader对象,构造方法中绑定要读取的数据源
  2. 使用FileReader对象中的方法read读取文件
  3. 释放资源
样例
package fileReadAndWrite;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建FileReader对象,构造方法中绑定要读取的数据源
		FileReader reader = new FileReader("C:\\aaa\\c.txt");
		
		// 2. 使用FileReader对象中的方法read读取文件
		// 注意使用:字符数组哟
		int len = 0;
		char[] buf = new char[1024];
		while((len = reader.read(buf)) != -1) {
			System.out.println(new String(buf,0,len));
		}
		
		// 3. 释放资源
		reader.close();
		
	}

}

写文件(未使用缓冲对)

FileWriter

创建方法

方法

概述

FileWriter(File file)

给一个File对象构造一个FileWriter对象

FileWriter(File file, boolean append)

给一个File对象构造一个FileWriter对象

FileWriter(String fileName)

构造一个给定文件名的FileWriter对象

FileWriter(String fileName, boolean append)

构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据

常用方法

返回值

方法

概述

void

write(int c)

写一个字符

void

write(char[] cbuf, int off, int len)

写入字符数组的一部分

void

write(String str, int off, int len)

写一个字符串的一部分

void

flush()

刷新流

void

close()

关闭流,先刷新

使用步骤
  1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
  2. 使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
  3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)
样例
package fileReadAndWrite;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		//	1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
		// 第二个参数,书写boolean值。是否追加
		FileWriter writer = new FileWriter("C:\\aaa\\d.txt", true);
		
		//	2. 使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
		// 换行依旧:
		// windows:\r\n
		// linux: /n
		// mac : /r
		writer.write("你好");
		writer.write("\r\n");
		writer.write("你好");
		writer.write("\r\n");
		writer.write("你好程序员",2,3);
		//	3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
		writer.flush();
		//	4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)
		writer.close();
	}

}

读文件(使用缓冲对)

BufferedReader

创建方法

方法

概述

BufferedReader(Reader in)

创建使用默认大小的输入缓冲区的缓冲字符输入流

BufferedReader(Reader in, int sz)

创建使用指定大小的输入缓冲区的缓冲字符输入流

常用方法

返回值

方法

概述

String

readLine()

读一行文字

void

close()

关闭流并释放与之相关联的任何系统资源

使用步骤
  1. 创建字符缓冲输入流对象,构造方法中传递字符输入流
  2. 使用字符缓冲输入流对象中的方法read/readLine读取文本
  3. 释放资源
样例
package fileReadAndWrite;

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 {
		// TODO Auto-generated method stub
		// 1. 创建字符缓冲输入流对象,构造方法中传递字符输入流
		BufferedReader reader = new BufferedReader(new FileReader("C:\\aaa\\d.txt"));
		// 2. 使用字符缓冲输入流对象中的方法read/readLine读取文本
		String len = null;
		while( (len = reader.readLine()) != null) {
			System.out.println(len);
		}
		// 3. 释放资源
		reader.close();
	}

}

写文件(使用缓冲对)

BufferedWriter

创建方法

方法

概述

BufferedWriter(Writer out)

创建使用默认大小的输出缓冲区的缓冲字符输出流

BufferedWriter(Writer out, int sz)

创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区

常用方法

返回值

方法

概述

void

write(int c)

写一个字符

void

write(char[] cbuf)

写入字符数组

void

write(String s)

写入字符串

void

write(char[] cbuf, int off, int len)

写入字符数组的一部分

void

write(String s, int off, int len)

写一个字符串的一部分

void

newLine()

写一行行分隔符

void

close()

关闭流,先刷新

void

flush()

刷新流

使用步骤
  1. 创建字符缓冲输出流对象,构造方法中传递字符输出流
  2. 调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
  3. 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源
样例
package fileReadAndWrite;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建字符缓冲输出流对象,构造方法中传递字符输出流
		BufferedWriter writer = new BufferedWriter(new FileWriter("C:\\aaa\\d.txt",true));
		// 2. 调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
		writer.newLine();
		writer.write("我是一个假程序员");
		writer.newLine();
		writer.write("我是一个假程序员",2,5);
		
		// 3. 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
		writer.flush();
		// 4. 释放资源
		writer.close();
	}
}

通往字符流—>字节流桥梁(解决不同编码格式可正常读取)

读文件

InputStreamReader

创建方法

方法

概述

InputStreamReader(InputStream in)

使用默认编码格式读文件

InputStreamReader(InputStream in, String charsetName)

指定编码格式读文件

常用方法

返回值

方法

概述

int

read()

读一个字符

int

read(char[] cbuf )

一次读取多个字符,将字符送入字符数组

void

close()

关闭流并释放与之相关联的任何系统资源

使用步骤
  1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
  2. 使用InputStreamReader对象中的方法read读取文件
  3. 釋放资源
注意事项
  1. 构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码
样例
package fileReadAndWrite;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class InputStreamReaderTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
		
		InputStreamReader reader = new InputStreamReader(new FileInputStream("C:\\aaa\\d.txt"),"gbk");
		// 2. 使用InputStreamReader对象中的方法read读取文件
		int len = 0;
		char[] buf = new char[1024];
		while((len = reader.read(buf)) != -1) {
			System.out.println(new String(buf,0,len));
		}
		// 3. 釋放资源
		reader.close();
	}

}

写文件

OutputStreamWriter

创建方法

方法

概述

OutputStreamWriter(OutputStream out)

使用默认编码格式读文件

OutputStreamWriter(OutputStream out, String charsetName)

指定编码格式读文件

常用方法

返回值

方法

概述

void

write(int c)

写一个字符

void

write(char[] cbuf)

写入字符数组

void

write(String s)

写入字符串

void

write(char[] cbuf, int off, int len)

写入字符数组的一部分

void

write(String s, int off, int len)

写一个字符串的一部分

void

close()

关闭流,先刷新

void

flush()

刷新流

使用步骤
  1. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
  2. 使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
  3. 使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
  4. 释放资源
样例
package fileReadAndWrite;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class OutputStreamWriterTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 1. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\aaa\\e.txt",true),"utf-8");
		// 2. 使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
		writer.write("你好啊程序员");
		writer.write("\r\n");
		writer.write("我不好啊,程序员",1,4);
		// 3. 使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
		writer.flush();
		// 4. 释放资源
		writer.close();
	}

}

综合案例

复制图片格式文件

注意事项

  1. 读取图片格式文件。只能使用字节流。
  2. 其余类似于文本文件,字符流更擅长
package fileReadAndWrite;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		
		// 1. 创建一个 可以 读文件 数据的一个对象。并指定,文件的地点
		// 2. 创建一个 可以 写文件 数据的一个对象。并指定,复制的路径
		BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("C:\\aaa\\1.jpg"));
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("C:\\aaa\\2.jpg"));
		
		// 3. 读取 需要 复制的图片的数据
		// 4. 将读取到的图片数据,传入到 指定复制路径
		int len = 0;
		byte[] buf = new byte[1024];
		while((len = bufferedInputStream.read(buf)) != -1) {
			bufferedOutputStream.write(buf,0,len);
		}

		// 5.关闭所有资源
		// 先关闭 输出流。再关闭输入流。因为如果 我输出流都已经关闭了。说明数据已经写完了。我可以理所当然的关闭输入流
		bufferedOutputStream.close();
		bufferedInputStream.close();
	}

}