开发中经常各种对文件的操作,也就是各种读写操作,原理明白了,什么场景用什么方法自然也就得心应手了。这里就简单总结下常用到的读写文件操作,留给需要的同学。

首先了解下输入输出流,它是相对的,程序为参照物。

输入流:程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道

输出流:程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

读写文件过程:

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();