1. FileInputStream :读取文件数据的输入字节流
字节流: 字节流读取的都是文件中的二进制数据,读取到二进制数据不会经过任何处理字符流: 读取的数据以字符为单位,也是读取二进制数据,但是会把二进制数据转化成我们能识别的数据。
字符流 = 字节流 + 解码
使用FileInputStream 读取文件数据的步骤:
1. 找到目标文件
2. 建立数据的输入通道
3. 读取文件的数据
4. 关闭资源
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
// readtxt();
// readtxt2();
// readtxt3();
readtxt4();
}
// 方式4 : 使用缓冲数组配合循环一起读取
public static void readtxt4() throws IOException {
long startime = System.currentTimeMillis();
File file = new File("C:\\Users\\fzx\\Desktop\\picture\\25.jpg");
FileInputStream fileInputStream = new FileInputStream(file);
int flag = 0;
byte[] buf = new byte[1024*3]; // 缓冲数组的长度一般是1024的倍数,缓冲数组越大,效率越高
while((flag = fileInputStream.read(buf) ) != -1) {
System.out.println(new String(buf, 0, flag));
}
fileInputStream.close();
long endtime = System.currentTimeMillis();
System.out.println("读取的时间是: " + (endtime-startime)); // 3176 S
}
// 方式3 : 使用缓冲数组读取, 缺点: 还是无法读取完整!!!!!
public static void readtxt3() throws IOException {
File file = new File("J:\\a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[4]; // 建立缓冲数组,读取文件数据
int length = fileInputStream.read(buf); //数据读取到字节数组中了,而read()返回的是本次读取了几个字节数据
String content = new String(buf,0,length); // 字节数组构建一个字符串
System.out.println(content);
fileInputStream.close();
}
// 方式2: 使用循环读取文件的数据
public static void readtxt2() throws IOException {
long startime = System.currentTimeMillis();
File file = new File("C:\\Users\\fzx\\Desktop\\picture\\25.jpg");
FileInputStream fileInputStream = new FileInputStream(file);
int flag = 0; // 如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
while((flag = fileInputStream.read() ) != -1) {
System.out.print((char)flag);
}
fileInputStream.close();
long endtime = System.currentTimeMillis();
System.out.println("读取的时间是: " + (endtime-startime)); // 7648 S
}
// 方式1: 缺点: 无法完整读取完
public static void readtxt() throws IOException{
File file = new File("J:\\a.txt"); // 1. 找到目标文件
FileInputStream fileInputStream = new FileInputStream(file); // 建立管道流
int content = fileInputStream.read(); // 读取文件中的数据, 读取一个字节的数据
System.out.println("读到的是: " + (char)content);
fileInputStream.close(); // 关闭资源, 实际上是释放资源
}
}
* 问题1: 读取完不关闭资源,有什么影响??? 其他程序无法对该资源进行其他操作 !!!!
* 问题二: 缓冲数组覆盖的方式,,还是清除?
2. FileOutputStream
注意的事项:* 1. 如果目标文件不存在,则会在FileOutputStream时自动创建该文件;
* 2. 如果目标文件已经存在,会先清空目标文件中的数据,然后写入数据
* 3. 如果在要原始数据追加,需要使用new FileOutputStream(file,true) 构造函数
* 4. write()方法写数据的时候,虽然接收的是一个int类型的数据,但是真正写出只是一个字节的数据, 只是把低8位的二进制数据写出,其他24位数据全部丢弃
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
writetxt_1();
}
public static void writetxt_1() throws IOException {
File file = new File("J:/a.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
String data = "abcdef";
byte[] buf = data.getBytes(); // 字符串转换成字节数组
fileOutputStream.write(buf, 0, 2); // 从指定字节数组的指定索引值开始写,2: 写出两个字节
fileOutputStream.close();
}
}
应用: 复制一张图片 (复制:读取 与 写入)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
FileInputStream fileInputStream =new FileInputStream(file);
File file2 = new File("J:/a.jpg");
// 每创建一个 FileOutputStream 的时候,默认情况下FileOutputStream指针指向文件的开始位置。 每写一次,指针都会相应移动
FileOutputStream fileOutputStream = new FileOutputStream(file2);
int length = 0;
byte[] buf = new byte[1024];
while ((length = fileInputStream.read(buf))!=-1) { // 边读边写
fileOutputStream.write(buf, 0, length);
}
fileOutputStream.close(); // 关闭资源原则: 先关闭后关,后开先关!!!!!
fileInputStream.close();
}
}
3. IO 异常处理
// 首先要阻止后面的代码执行return, 或者 throw ,而且需要通知调用者这里出错了
// return ; 这个可以阻止后面的代码执行,但是异常信息显示不了
// throw e ; 方法必须声明, 而且调用者 需要try{}catch{}
// 把IOException 传递给 RuntimeException 包装一层,然后再抛出,目的是为了让调用者使用变得灵活,方法不需要声明,调用者想处理或者不处理;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
copeimage();
}
public static void copeimage() {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
fileInputStream =new FileInputStream(file);
File file2 = new File("J:/a.jpg");
fileOutputStream = new FileOutputStream(file2);
int length = 0;
byte[] buf = new byte[1024];
while ((length = fileInputStream.read(buf))!=-1) {
fileOutputStream.write(buf, 0, length);
}
} catch (IOException e) {
System.out.println("拷贝图片失败");
throw new RuntimeException(e); // 第一个 RuntimeException
}finally {
try {
if(fileOutputStream !=null) {
fileOutputStream.close(); // 执行失败,后面的fileInputStream.close()则没机会执行
System.out.println("关闭输出流成功");
}
} catch (Exception e2) {
System.out.println("关闭输出流资源失败");
throw new RuntimeException(e2); // 第二个 RuntimeException
}finally {
try {
if(fileInputStream !=null) {
fileInputStream.close();
System.out.println("关闭输入流成功");
}
} catch (Exception e3) {
System.out.println("关闭输入流资源失败");
throw new RuntimeException(e3); // 第三个 RuntimeException
}
}
}
}
}
****************************************************************************************************
Exception in thread "main" 读取文件失败
java.lang.RuntimeException: java.io.FileNotFoundException: J:\aaaaa.txt (系统找不到指定的文件。)
at test.test_1.test_1.read(test_1.java:43)
at test.test_1.test_1.main(test_1.java:18)
Caused by: java.io.FileNotFoundException: J:\aaaaa.txt (系统找不到指定的文件。)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(Unknown Source)
at java.base/java.io.FileInputStream.<init>(Unknown Source)
at test.test_1.test_1.read(test_1.java:27)
... 1 more
4. BufferedInputStream: 缓冲输入字节流
* InputStream 输入字节流的基类。 抽象
* FileInputStream 读取文件数据的输入字节流
* BufferedInputStream 缓冲输入字节流 该类内部只不过是 维护了一个8kb的字节数组
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
private byte[] getBufIfOpen() throws IOException {
byte[] buffer = buf;
if (buffer == null)
throw new IOException("Stream closed");
return buffer;
}
// BufferedInputStream 本身不具备读文件的能力,所以需要借助 fileInputStream
* 使用 BufferedInputStream 步骤:
* 找到目标文件; 建立数据的输入通道; 建立缓冲输入字节流; 关闭资源
、、、、
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
readtxt_2();
}
// bufferedInputStream 读取进行对比
public static void readtxt_2() throws IOException {
File file = new File("J:\\a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
int content = 0;
while ( (content = bufferedInputStream.read() ) !=-1) {
System.out.println((char)content);
}
bufferedInputStream.close(); // 调用 bufferedInputStream 的 close()方法实际上是关闭fileInputStream
}
// fileInputStream 读取进行对比
public static void readtxt() throws IOException {
File file = new File("J:/a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[1024];
int length = 0;
while((length = fileInputStream.read(buf)) !=-1) {
System.out.println(new String(buf, 0, length));
}
fileInputStream.close();
}
}
// bufferedInputStream 和 fileInputStream 都是每次读一个字节,为什么bufferedInputStream效率高
5. BufferedOutputSream 缓冲输出字节流
* OutputStream 所有输出字节流的基类, 抽象类
* FileOutputSream
* BufferedOutputSream 缓冲输出字节流 内部维护一个8KB的字节流
* 注意事项:
* 1. 使用BufferedOutputSream写数据的时候,它write()方法是先把数据写到它内部维护的字节数组中
* 2. 如果要将数据写到硬盘,则需要调用flush()方法或者close()方法,或者内部维护的字节数组已经填满数据的时候
*/
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
File file = new File("J:/a.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bufferedOutputStream.write("\r\n付祖贤女侠".getBytes());
// bufferedOutputStream.flush();
bufferedOutputStream.close();
}
}
应用: 用缓冲字节流复制一张图片
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {
public static void main(String[] args) throws IOException {
copyimage ();
}
public static void copyimage () throws IOException {
File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
File file2 = new File("J:/a.jpg");
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file2);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
int content = 0;
// int length = bufferedInputStream.read(buf); // 传入缓冲数组,内容是存储在缓冲数组中,返回值是存储到缓冲数组中的字节个数
while((content = bufferedInputStream.read()) != -1) { //read()里面没有缓冲数组,返回值为读取到的内容
bufferedOutputStream.write(content);
// bufferedOutputStream.flush(); // 有这句代码 效率反而低
}
bufferedOutputStream.close();
bufferedInputStream.close();
}
}
应用: 使用字节流读取中文
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class test_1 {
public static void main(String[] args) throws IOException {
// write();
read_2();
}
// 使用字节流 读取 中文
public static void read_2() throws IOException {
File file = new File("J:/a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int content = 0;
byte[] buf = new byte[2];
while ((content = fileInputStream.read(buf))!=-1) {
System.out.println(new String(buf,0,content));
}
fileInputStream.close();
}
// 使用字节流 写入 中文
public static void write() throws IOException {
File file = new File("J:/a.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
String data = "付祖贤女侠";
byte[] data_1 = data.getBytes(); //字节流之所以能够写中文是因为借助了字符串的getBytes()方法对字符串进行编码
System.out.println(Arrays.toString(data_1));
fileOutputStream.write(data_1);
fileOutputStream.close();
}
}
//
//