文件字节输入流:FileInputStream
- 作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
构造器 | 说明 |
public FilelnputStream(File file) | 创建字节输入流管道与源文件对象接通 |
public FilelnputStream(String pathname) | 创建字节输入流管道与源文件路径接通 |
方法名称 | 说明 |
public int read() | 每次读取一个字节返回,如果字节已经没有可读的返回-1 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
import java.io.*;
/*
data.txt:231
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建一个文件字节输入流管道与源文件接通
InputStream is = new FileInputStream("file-io-app\\src\\data.txt");
//读取一个字节返回
// int b1 = is.read();
// System.out.println((char)b1);
//
// int b2 = is.read();
// System.out.println((char)b2);
//
// int b3 = is.read();
// System.out.println((char)b3);
//
// int b4 = is.read(); //读取完毕返回-1
// System.out.println(b4);
//使用循环改进
//定义一个变量记录每次读取的字节,读中文会乱码
int b;
while (( b = is.read()) != -1){
System.out.print((char) b);//231
}
}
}
import java.io.FileInputStream;
import java.io.InputStream;
/*
data.txt : ab1abcdf
*/
public class FileInputStreamDemo2 {
public static void main(String[] args) throws Exception {
//创建一个文件字节输入流管道
InputStream is = new FileInputStream("file-io-app\\src\\data.txt");
//定义一个字节数组,用于读取字节数组
// byte[] buffer = new byte[3];
// int len = is.read(buffer);
// System.out.println("读取了"+ len +"个字节");//读取了3个字节
// String rs = new String(buffer);
// System.out.println(rs);//ab1
//
// int len2 = is.read(buffer);
// System.out.println("读取了"+ len2 +"个字节");//读取了3个字节
// String rs2 = new String(buffer);
// System.out.println(rs2);//abc
//
// int len3 = is.read(buffer);
// System.out.println("读取了"+ len3 +"个字节");//读取了2个字节
// //读取多少输出多少
// String rs3 = new String(buffer,0,len3);
// System.out.println(rs3);//df
//
// int len4 = is.read(buffer);
// System.out.println(len4);//-1
//改进使用循环,每次读取一个字节数组,读取中文无法避免乱码问题
byte[] buffer = new byte[3];
int len;//记录每次读取的字节数
while((len = is.read(buffer)) != -1){
//读取多少输出多少
System.out.print(new String(buffer,0,len)); //ab1abcdf
}
}
}
1、如何使用字节输入流读取中文内容输出不乱码呢?
- 定义一个与文件一样大的字节数组,一次性读取完文件的全部字节。
2、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?
- 如果文件过大,字节数组可能引起内存溢出。
一次性读取完文件的全部字节的方式
方式一
- 自己定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成。
方法名称 | 说明 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
方式二
- 官方为字节输入流InputStream提供了如下API可以直接把文件的全部数据读取到一个字节数组中
方法名称 | 说明 |
public byte[] readAllBytes() throws lOException | 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回 |
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/*
使用文件字节输入流一次读完文件的全部字节。可以解决乱码问题。
data.txt : ab1abcdffgs在v发表脂肪酸
*/
public class FileInputStreamDemo3 {
public static void main(String[] args) throws Exception {
//创建一个文件字节输入流管道与源文件接通
File file = new File("file-io-app\\src\\data.txt");
InputStream is = new FileInputStream(file);
//定义一个字节数组与文件的大小刚刚一样大
// byte[] buffer = new byte[(int) file.length()];
// int length = is.read(buffer);
// System.out.println("读取了"+length+"个字节");//读取了30个字节
// System.out.println("文件大小"+file.length());//文件大小30
// System.out.println(new String(buffer));//ab1abcdffgs在v发表脂肪酸
//读取全部字节,jdk9开始有的
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
}
}
文件字节输出流(FileOutputStream)
文件字节输出流(FileOutputStream)写数据出去的API
方法名称 | 说明 |
public void write(int a) | 写一个字节出去 |
public void write(byte[ ] buffer) | 写一个字节数组出去 |
public void write(byte[ ] buffer , int pos , int len) | 写一个字节数组的一部分出去 |
流的关闭与刷新
方法 | 说明 |
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
字节输出流实现数据追加
public FileOutputStream(String filepath, boolean append)创建字节输出流管道与源文件路径接通,可追加数据
字节输出流实现写出去的数据能换行
os.write("\r\n" .getBytes())
实例:文件拷贝
import java.io.*;
/*
支持一切文件的复制
*/
public class FileInputStreamDemo4 {
public static void main(String[] args) {
try {
InputStream is = new FileInputStream("D:\\qt_projects\\qt_pro\\matrix.mov");
//创建字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("D:\\java_projects\\resources\\matrix.mov");
//定义一个字节数组转移数据
byte[] buffer = new byte[1024];
int len;//记录每次读取的字节数
while((len = is.read(buffer))!= -1){
os.write(buffer,0,len);
}
System.out.println("复制完成了");
//关闭流
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
资源释放方式
try-catch-finally
- finally:在异常处理时提供finally块来执行所有清除操作,比如说IO流中的释放资源
- 特点:被finally控制的语句最终一定会执行,除非JVM退出
- 异常处理标准格式: try....catch...finally
try-catch-finally格式:
try {
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(97);
fos.close();
} catch(IOException e){
e.printStackTrace();
}finally{
}
finally虽然可以用于释放资源,但是释放资源的代码过于繁琐
JDK7改进方案:
try(定义流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
//资源用完最终自动释放
注意
JDK7以及JDK9的try()中只能放置资源对象,否则报错。
资源都是实现了Closeable/AutoCloseable接口的类对象
public abstract class InputStream implements Closeable {}
public abstract class OutputStream implements Closeable,Flushable{}
JDK9改进方案:
定义输入流对象;
定义输出流对象;
try(输入流对象;输出流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
//资源用完最终自动释放