开发中经常各种对文件的操作,也就是各种读写操作,原理明白了,什么场景用什么方法自然也就得心应手了。这里就简单总结下常用到的读写文件操作,留给需要的同学。
首先了解下输入输出流,它是相对的,程序为参照物。
输入流:程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道
输出流:程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。
读写文件过程:
file(内存)----输入流---->【程序】----输出流---->file(内存)
常用的读文件方法:
// 向文件写入内容(输出流)
String str = "每日运维";
byte bt[] = new byte[1024]; //每次写入量
bt = str.getBytes();
FileOutputStream in = new FileOutputStream(file);
in.write(bt, 0, bt.length);
in.close();
// 读取文件内容 (输入流)
FileInputStream out = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(out);
int ch = 0;
while ((ch = isr.read()) != -1) {
System.out.print((char) ch);
1.以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。
File file = new File(fileName);
//以字节为单位读取文件内容,一次读一个字节
InputStream in = new FileInputStream(file);
int tempbyte;
while ((tempbyte = in.read()) != -1) {
System.out.write(tempbyte);
}
in.close();
// 一次读多个字节
byte[] tempbytes = new byte[100];
int byteread = 0;
InputStream in = new FileInputStream(fileName);
ReadFromFile.showAvailableBytes(in); //显示待读取字节
// 读入多个字节到字节数组中,byteread为一次读入的字节数
while ((byteread = in.read(tempbytes)) != -1) {
System.out.write(tempbytes, 0, byteread);
}
2.以字符为单位读取文件,常用于读文本,数字等类型的文件
File file = new File(fileName);
//以字符为单位读取文件内容,一次读一个字节
Reader reader = new InputStreamReader(new FileInputStream(file));
int tempchar;
while ((tempchar = reader.read()) != -1) {
// 对于windows下,rn这两个字符在一起时,表示一个换行,但如果这两个字符分开显示时,会换两次行。屏蔽掉r,或者屏蔽n。否则,将会多出很多空行。
if (((char) tempchar) != 'r') {
System.out.print((char) tempchar);
}
}
reader.close();
//以字符为单位读取文件内容,一次读多个字节
char[] tempchars = new char[30];
int charread = 0;
Reader reader = new InputStreamReader(new FileInputStream(fileName));
// 读入多个字符到字符数组中,charread为一次读取字符数
while ((charread = reader.read(tempchars)) != -1) {
// 同样屏蔽掉r不显示
if ((charread == tempchars.length) && (tempchars[tempchars.length - 1] != 'r')) {
System.out.print(tempchars);
} else {
for (int i = 0; i < charread; i++) {
if (tempchars[i] == 'r') {
continue;
} else {
System.out.print(tempchars[i]);
}
}
}
}
3.以行为单位读取文件,常用于读面向行的格式化文件
File file = new File(fileName);
//以行为单位读取文件内容,一次读一整行
BufferedReader reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
while ((tempString = reader.readLine()) != null) {
System.out.println("line " + line + ": " + tempString);
line++;
}
reader.close();
4.随机读取文件内容
RandomAccessFile randomFile = new RandomAccessFile(fileName, "r");
long fileLength = randomFile.length();
// 读文件的起始位置
int beginIndex = (fileLength > 4) ? 4 : 0;
// 将读文件的开始位置移到beginIndex位置。
randomFile.seek(beginIndex);
byte[] bytes = new byte[10];
int byteread = 0;
// 一次读10个字节,如果文件内容不足10个字节,则读剩下的字节。
// 将一次读取的字节数赋给byteread
while ((byteread = randomFile.read(bytes)) != -1) {
System.out.write(bytes, 0, byteread);
}
5.文件读取(Memory mapping-内存映射方式)效率最好
File f = new File(“test.txt");
FileInputStream in = new FileInputStream(f);
FileChannel chan = in.getChannel();//内存与磁盘文件的通道,获取通道,通过文件通道读写文件。
MappedByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
byte[] b = new byte[(int) f.length()];
int len = 0;
while(buf.hasRemaining()){
b[len] = buf.get();
len++;
}
chan.close();
in.close();
常用的写文件方法:
1.使用RandomAccessFile
// 打开一个随机访问文件流,按读写方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
// 文件长度,字节数
long fileLength = randomFile.length();
// 将写文件指针移到文件尾。
randomFile.seek(fileLength);
randomFile.writeBytes(content);
randomFile.close();
补充:
RandomAccessFile的对象包含一个记录指针,用于标识当前流的读写位置,这个位置可以向前移动,也可以向后移动。RandomAccessFile包含两个方法来操作文件记录指针。
long getFilePoint():记录文件指针的当前位置。
void seek(long pos):将文件记录指针定位到pos位置。
2.使用FileWriter
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
FileWriter writer = new FileWriter(fileName, true);
writer.write(content);
writer.close();
3.使用内存映射实现文件复制操作
File f = new File("E:"+File.separator+"test.txt");
FileInputStream in = new FileInputStream(f);
FileOutputStream out = new FileOutputStream("F:"+File.separator+"test2.txt");
FileChannel inChan = in.getChannel();
FileChannel outChan = out.getChannel();
//开辟缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
while ((inChan.read(buf)) != -1){
//重设缓冲区
buf.flip();
//输出缓冲区
outChan.write(buf);
//清空缓冲区
buf.clear();
}
inChan.close();
outChan.close();
in.close();
out.close();