1、创建 file
2、创建 reader writer
3、 读写操作
4、关闭流
5、try-catch 捕获错误
package com.fileReader;
import org.junit.Test;
import java.io.*;
/**
* ClassName: TestRederAndWriter
* Package: com.fileReader
* Description:
*
* @Author Samuel
* @Create 2024/7/17 09:19
* @Version 1.0
*/
public class TestRederAndWriter {
@Test
public void Test() {
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
//创建file
File file = new File("src/com/fileReader/testWriter");
//创建 reader
fileReader = new FileReader(file);
/**
* FileWriter(String fileName)
* FileWriter(String fileName, boolean append)
* FileWriter(File file)
* FileWriter(File file, boolean append)
* FileWriter(FileDescriptor fd)
* FileWriter(String fileName, Charset charset)
* FileWriter(String fileName, Charset charset, boolean append)
* FileWriter(File file, Charset charset)
* FileWriter(File file, Charset charset, boolean append)
*/
//append or replace
fileWriter = new FileWriter("src/com/fileReader/testWriter_copy",false);
//read and writer
char[] chars = new char[5];
int length;
while ((length = fileReader.read(chars)) != -1) {
/**
* cbuf – Buffer of characters
* off – Offset from which to start writing characters
* len – Number of characters to write
*/
fileWriter.write(chars, 0, length);
}
System.out.println("写入成功");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//close
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
输入流 | inputStream | reader |
输出流 | outputStream | writer |
类型 | 字节流 | 字符流 |
是否为直接写入:节点流(FileInputStream、FileOutputStream、FileReader、FileWriter)、 处理流
字符流只能处理文本文件 txt java .c .py
字节流处理 图片、视频、音频等文件、也可以处理文本文件 .doc .pdf .xls .avi
节点流加载文件 默认以当前模块为相对路径
getResourceAsStream 以当前类路径/src为默认相对路径
WriterFile 的构造函数可以接受第二个参数,来确定写入模式是 append 还是 replace
write 方法 接收 char[] 时可以接收 写入的起始和结束位置
FileInputStream 读取中文字节到控制台显示乱码的问题?
当统一输入到某个文件不会乱码 ,FileOutputStream。但是 由于设置的 字节 buffer [] 。
将某一个文字 分割开运送时,打印就会出现乱码。
eg:
123中文 9个字节 设置buffer 为 byte[5]
第一轮:123和【中】的前两个字节
第二轮:【中】的第三个字节和【文】的三个字节
但是每轮打印 并没有将字节合并 、无法显示为正常文字
BufferReader/Writer
区别:readLine 方法 :不读换行符,读完返回null,
write 写时,手动加换行符,或者调用 newLine 方法
package com.fileReader;
import org.junit.Test;
import java.io.*;
/**
* ClassName: BufferStreamCopy
* Package: com.fileReader
* Description:
*
* @Author Samuel
* @Create 2024/7/18 11:06
* @Version 1.0
*/
public class BufferStreamCopy {
@Test
public void test() {
long startTime = System.currentTimeMillis();
String src = "src/com/fileReader/big_file.zip";
String dest = "src/com/fileReader/big_file_copy.zip";
String dest2 = "src/com/fileReader/big_file_copy2.zip";
// FileStreamCopy(src, dest); //2034
BufferStreamCopy(src, dest2); //437
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
public void FileStreamCopy(String src, String dest) {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
File file = new File(src);
fileInputStream = new FileInputStream(file);
// File file1 = new File("src/com/fileReader/src_copy.jpeg");
fileOutputStream = new FileOutputStream(dest);
byte[] bytes = new byte[1024];
int length;
/** 注意 read(bytes) */
while ((length = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, length);
// System.out.print(new String(bytes,0,length));
}
System.out.println("写入成功");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public void BufferStreamCopy(String src, String dest) {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
//file
File src_file = new File(src);
File des_file = new File(dest);
//reader writer
FileInputStream fileInputStream = new FileInputStream(src_file);
FileOutputStream fileOutputStream = new FileOutputStream(des_file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//read write
byte[] bytes = new byte[1024];
int length;
while ((length = bufferedInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, length);
}
System.out.println("复制完成");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
bufferedOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Test
public void BufferStreamCopyText() {
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
//file
FileReader fileReader = new FileReader("src/com/fileReader/testWriter");
FileWriter fileWriter = new FileWriter("src/com/fileReader/testWriter_copy_by_readLine");
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);
String StringLine;
while ((StringLine = bufferedReader.readLine()) != null) {
/**
* 特征 不会读换行,需要手动换行
A String containing the contents of the line, not including any line-termination characters,
or null if the end of the stream has been reached without reading any characters
*/
//1、
bufferedWriter.write(StringLine + "\n");
//2、 bufferedWriter.newLine();
}
System.out.println("复制完成");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
转换流
inputStreamReader :将磁盘文件将字节转成字符读取到内存
outputStreamWriter:将内存内容字符转字节存到磁盘
不同的编码格式 utf-8 vs gbk 导致乱码的原因
GBK 格式是中华人民共和国国家标准的字符编码,由原国家技术监督局发布,编号为 GB 18030-2000。GBK 是 GB2312 的扩展,兼容 GB2312,并增加了部分中日韩统一表意文字。
win默认采用 gbk 编码存储,而ider默认采用 utf-8格式,当用 idea打开 win编码的文本会乱码。
解决是idea 读取的时候设置 gbk的读取方式。
package com.fileReader;
import org.junit.Test;
import java.io.*;
/**
* ClassName: InputStreamReader_Writer
* Package: com.fileReader
* Description:
*
* @Author Samuel
* @Create 2024/7/18 16:36
* @Version 1.0
*/
public class InputStreamReader_Writer {
@Test
public void test() throws IOException {
//磁盘是 gbk
File file = new File("src/com/fileReader/txt_gb18030.txt");
FileInputStream fileInputStream = new FileInputStream(file);
//以gbk读取展示控制台正常展示
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "gbk");
FileOutputStream fileOutputStream = new FileOutputStream("src/com/fileReader/txt_gb18030_copy.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
char[] chars = new char[10];
int length;
while ((length = inputStreamReader.read(chars)) != -1) {
//1、默认以 utf-8 格式将字符写入到磁盘
// outputStreamWriter.write(chars, 0, length);
//2、自定义读取 默认是 utf-8
String str = new String(chars, 0, length);
/**
* void getBytes(int, int, byte[], int)
* byte[] getBytes(String)
* byte[] getBytes(Charset)
* byte[] getBytes()
* void getBytes(byte[], int, byte)
* void getBytes(byte[], int, int, byte, int)
*/
byte[] bytes = str.getBytes(); //如果传gbk 展示会乱码 mac、idea默认都是 utf-8
fileOutputStream.write(bytes);
}
inputStreamReader.close();
outputStreamWriter.close();
/**
* idea 默认用的 utf-8
* 在使用UTF-8编码时,
* 中文字符通常占用3个字节,而在GBK编码(或类似的双字节编码)中,中文字符占用2个字节。
* 如果一个以GBK编码保存的中文文本文件在默认使用UTF-8编码的IDE中打开,由于编码解释方式的差异,
* 原本的中文字符会被错误解析,导致显示乱码
*/
}
}