NingG +

Java中文件读写

分析

开篇即开扯,数年前,我被某人问道java如何进行文件读写,具体:从FileA中读取内容,并追加写入FileB内。我一听,简单呀,几个步骤:

打完收工,简简单单;然后,某人递给我一张纸,“把上述过程的java代码写到纸上吧”。沉思2分钟,我x,“我不会”。

文件读写的基本原理

(涉及到stream层面的内容)

补充梳理

(涉及到class之间的继承关系,简洁的应用代码)

读取文件,两个维度:

分类:byte和char

差异:char是人眼可以识别的内容,可用于进行正则匹配或搜索;但需要经过一次byte与char之间的转换;

疑问:到底有什么差异?上面只是自己直观的感受,可能有误差;需要查证一下,产生两种方式的原因;

按char读写

字符,是人眼可以识别的内容,可以进行正则匹配;java.io.Readerjava.io.Writer,按字符(character)读写文件,具体几种方式:

按byte读写

字节,机器识别的内容;java.io.InputStreamjava.io.OutputStream,具体几种方式:

思考:Buffered中详细的机制,特别是其中几个方法:mark()skip()reset()ready()等等;

FileReader & FileWriter

java.io.FileReader和java.io.FileWriter,几点:

疑问byte-buffer size什么东西?

程序的处理过程,几点:

核心代码:

File srcFile = new File(srcFilename);
File destFile = new File(destFilename);

FileReader srcFileReader = new FileReader(srcFile);
FileWriter destFileWriter = new FileWriter(destFile);

char[] bufChar = new char[1000];
int bufLen = -1;

while( (bufLen = srcFileReader.read(bufChar)) != -1 ){
	destFileWriter.write(bufChar, 0, bufLen);
	Arrays.fill(bufChar, '\0');
}

destFileWriter.flush();
destFileWriter.close();
srcFileReader.close();

完整示例代码如下:

package com.github.ningg;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

public class TestFile {

	public static void main(String[] args) throws IOException {
		
		String srcFilePath = "E:/2.log";
		String destFilePath = "E:/2char.log";
		
		File srcFile = new File(srcFilePath);
		File destFile = new File(destFilePath);
		
		FileReader fileReader = new FileReader(srcFile);
		FileWriter fileWriter = new FileWriter(destFile);
		
		char[] charArray = new char[1000];
		int charLen = -1;
		
		while ( (charLen = fileReader.read(charArray)) != -1) {
			System.out.println(Arrays.toString(charArray));
			fileWriter.write(charArray, 0, charLen);
			Arrays.fill(charArray, '\0');
		};
		
		fileWriter.flush();
		fileReader.close();
		fileWriter.close();
		
	}
}

疑问:上述FileReader.read()FileWriter.write(),其中,write()本质是覆盖写,是否有追加写?

疑问:按照char的方式读写文件时,FileReaderFileWriter利用了默认的编码方式,通常是UTF-8;那,有没有按照char方式读写文件,同时可以指定charset的办法呢?

InputStreamReader & OutputStreamWriter

完整示例代码如下:

package com.github.ningg;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;

public class InputStreamReaderAndOutputStreamWriter {

	public static void main(String[] args) throws IOException {
		
		String charset = "GBK";

		String srcFilepath = "E:/1.log";
		String destFilepath = "E:/1char.log";
		
		FileInputStream srcFileInputStream = new FileInputStream(srcFilepath);
		FileOutputStream destFileOutputStream = new FileOutputStream(destFilepath);
		
		InputStreamReader srcStreamReader = new InputStreamReader(srcFileInputStream, charset);
		OutputStreamWriter destStreamWriter = new OutputStreamWriter(destFileOutputStream, charset);
		
		char bufChar[] = new char[1000];
		int bufLen = -1;
		
		while( (bufLen = srcStreamReader.read(bufChar)) != -1 ){
			destStreamWriter.write(bufChar, 0, bufLen);
			System.out.println(Arrays.toString(bufChar));
			Arrays.fill(bufChar, '\0');
		}
		
		destStreamWriter.flush();
		destStreamWriter.close();
		srcStreamReader.close();
		
	}
}

BufferedReader & BufferedWriter

思考:BufferedReader和BufferedWriter的实现机制?

完整示例代码如下:

package com.github.ningg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class BufferedReaderAndBufferedWriter {

	public static void main(String[] args) throws IOException {
		
		String srcFile = "E:/1.log";
		String destFile = "E:/lbuf.log";
		String charset = "GBK";
		
		FileInputStream fileInputStream = new FileInputStream(srcFile);
		FileOutputStream fileOutputStream = new FileOutputStream(destFile);
		
		InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charset);
		OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, charset);
		
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
		BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
		
		String inputLine = null;
		
		while((inputLine = bufferedReader.readLine()) != null ){
			bufferedWriter.write(inputLine);
			bufferedWriter.newLine();
			System.out.println(inputLine);
		}
		
		bufferedWriter.flush();
		bufferedWriter.close();
		bufferedReader.close();
		
		fileOutputStream.flush();
		fileOutputStream.close();
		fileInputStream.close();
	}
}

思考:几个方法的作用,以及联系:

小结:只要最高级的Reader、Writer、InputStream、OutputStream,完成flush\close,则无需向下递归;

备注:上述InputStream、OutputStream、Reader、Writer,之间关系的图形化表述;(TODO:需要一张图来表示其中的联系)

FileInputStream & FileOutputStream

完整示例代码如下:

package com.github.ningg;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class FileInputStreamAndFileOutputStream {

	public static void main(String[] args) throws IOException {
		
		String srcFilepath = "E:/1.log";
		String destFilepath = "E:/1byte.log";
		
		FileInputStream srcInputStream = new FileInputStream(srcFilepath);
		FileOutputStream destOutputStream = new FileOutputStream(destFilepath);
		
		byte[] bufByte = new byte[1000];
		int bufLen = -1;
		
		while( (bufLen = srcInputStream.read(bufByte)) != -1 ){
			destOutputStream.write(bufByte, 0, bufLen);
			System.out.println(Arrays.toString(bufByte));
		}
		
		destOutputStream.flush();
		destOutputStream.close();
		srcInputStream.close();
		
	}
}

BufferedInputStream & BufferedOutputStream

完整示例代码如下:

package com.github.ningg;

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

public class BufferedInputStreamAndBufferedOutputStream {

	public static void main(String[] args) throws IOException {
		
		String srcFile = "E:/1.log";
		String destFile = "E:/1BufByte.log";
		
		FileInputStream fileInputStream = new FileInputStream(srcFile);
		FileOutputStream fileOutputStream = new FileOutputStream(destFile);
		
		BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
		
		byte[] byteBuf = new byte[1000];
		int byteLen = -1;
		
		while( (byteLen = bufferedInputStream.read(byteBuf)) != -1 ){
			bufferedOutputStream.write(byteBuf, 0, byteLen);
		}
		
		bufferedOutputStream.flush();
		bufferedOutputStream.close();
		bufferedInputStream.close();
		
	}
}

参考来源

TODO

几点:

Top