Java 的 IO 流
- 字节流, 字节流可以操作任何数据, 计算机中存储是字节流
- InputStream
- OutputStream
- 字符流, 只能操作纯字符数据, 比较方便
- Reader
- Writer
使用IO流要导入包, 使用时要进行异常处理, 使用后要释放资源
FileInputStream 读取一个文件
import java.io.FileInputStream;
import java.io.IOException;
public class Demo1_FileInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fps = new FileInputStream("test.txt");
int x;
while ((x = fps.read() ) != -1){
System.out.println(x);
}
fps.close();
}
}
read() 为什么接收的int类型
因为字节输入流可以操作任意类型的文件,比如图片音频等, 这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte, 有可能在读到中间的时候遇到111111111,那么这11111111是byte类型的-1, 我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收, 如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完, 而结束标记的-1就是int类型
字节输出流 write()
- void write(int b) throws IOException 在输出时int 去掉前3个byte字节, 写入第4个byte到文件中, 这个写是覆盖
import java.io.FileOutputStream;
import java.io.IOException;
public class Deom2_FileOutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fps = new FileOutputStream("test.txt");
fps.write(100);
fps.write(101);
fps.write(102);
fps.close();
}
}
字节输出流 追加
- FileOutputStream(File file, boolean append) throws FileNotFoundException 输出字节流是否选择追加
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3_FileOutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fps = new FileOutputStream("test.txt", true);
fps.write(100);
fps.write(101);
fps.close();
}
}
复制文件
- byte字节读取, byte复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4_FileInOutStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
int b = 0;
while ( (b = fis.read() )!= -1){
fos.write(b);
}
fis.close();
fos.close();
}
}
FileInputStream 的 available方法
- int available() throws IOException 返回输入流的长度
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo5_FileInOutStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
int len = fis.available();
byte[] arr = new byte[fis.available()];
fis.read(arr);
fos.write(arr);
fis.close();
fos.close();
}
}
通过数组 byte[] 读取写入
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo6_FileInOutStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
byte[] arr = new byte[1024 * 1024];
int b = 0;
while ( (b =fis.read(arr)) != -1 ){
fos.write(arr,0,b);
}
fis.close();
fos.close();
}
private static void errSimple() throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
byte[] arr = new byte[3];
int b = 0;
while ( (b =fis.read(arr)) != -1 ){
fos.write(arr);
}
fis.close();
fos.close();
}
}
BufferedInputStream BufferedOutputStream
- 原码先读取1024*8个字节到内存, 复制给 BufferedOutputStream 1024*8 然后才写入文件
- 只需要关闭BufferedInputStream BufferedOutputStream 就能关闭所有流
import java.io.*;
public class Demo7_BufferInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b ;
while( ( b = bis.read() ) != -1){
bos.write(b);
}
// 只需关闭 BufferedInputStream BufferedOutputStream
bis.close();
bos.close();
}
}
flush和close方法的区别
- flush 刷新缓冲区, 缓冲区写到文件中, 刷完可以继续写.
- close 关闭前 就会刷新缓冲区 将缓冲区内容存到文件中
import java.io.*;
public class Demo8_FlushClose {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b ;
while ( (b = bis.read()) != -1 ){
bos.write(b);
bos.flush();
}
bis.close();
bos.close();
}
}
字节流读取中文有乱码
- UTF-8中英文1个字节, 中文3个字节, 按字节读取都会读出乱码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class Demo9_CharIO {
public static void main(String[] args) throws IOException {
// Demo1();
FileOutputStream fos = new FileOutputStream("chinese.txt");
fos.write("你好啊, 世界!".getBytes(StandardCharsets.UTF_8));
fos.write("\r".getBytes(StandardCharsets.UTF_8));
fos.close();
}
private static void Demo1() throws IOException {
FileInputStream fis = new FileInputStream("chinese.txt");
byte[] arr = new byte[3];
String s;
int len ;
while ( ( len=fis.read(arr) ) != -1){
System.out.println(new String(arr,0,len));
}
}
}
异常处理
- 流初始化null
- try 关闭流
- 能关闭一个就关闭一个
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo10_IOException {
public static void main(String[] args) throws IOException{
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("test.txt");
fos = new FileOutputStream("copy.txt");
}
finally {
try{
if(null != fis){
fis.close();
}
} finally {
if(null != fos){
fos.close();
}
}
}
}
}
图片加密解密
- 加密把输出的字节异或一个数, 解密时再异或这个数
import java.io.*;
public class Demo12_Encrypt {
public static void main(String[] args) throws IOException {
String src = "beauty.png";
String dest = "copy.png";
String dest2 = "copy1.png";
// extracted(src, dest);
extracted(dest, dest2);
}
private static void extracted( String src, String dest) throws IOException {
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(dest));
int b ;
while ( (b = fis.read()) != -1){
fos.write(b ^ 123 );
}
fis.close();
fos.close();
}
}
输入文件复制到当前路径下
import java.io.*;
import java.util.Scanner;
public class Demo13_CopyFile {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String src = null;
if(sc.hasNext()){
src = sc.nextLine();
}
BufferedInputStream fis =null;
int b ;
BufferedOutputStream fos = null;
if(src != null){
File file = new File(src);
fis = new BufferedInputStream(new FileInputStream(src));
fos = new BufferedOutputStream(new FileOutputStream("./"+file.getName()));
if( file.isFile()){
while ( (b = fis.read()) != -1){
fos.write(b);
}
} else if( file.isDirectory()){
System.out.println("文件夹无法复制");
}
}
fis.close();
fos.close();
}
}
练习, 录入输入字符到文件中
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Demo14_InputKey {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.txt", true));
String input = null;
while ( sc.hasNext()){
input = sc.nextLine();
if( "quit".equals(input)){
break;
} else{
bos.write(input.getBytes(StandardCharsets.UTF_8));
bos.write("\n".getBytes(StandardCharsets.UTF_8));
}
}
bos.close();
}
}