A. java文件复制(bufferedreader读取一个文件内容,用bufferedwriter 写入到另一个文件)
可以通过BufferedReader 流的形式进行流读取,之后通过readLine方法获取到每行的内容,之后通过bufferedwriter (如:OutputStreamWriter)。
BufferedReader bre = null;
OutputStreamWriter pw = null;//定义一个流
try {
String file = "D:/test/test.txt";
bre = new BufferedReader(new FileReader(file));//此时获取到的bre就是整个文件的缓存流
pw = new OutputStreamWriter(new FileOutputStream(“D:/test.txt”),"GBK");//确认流的输出文件和编码格式,此过程创建了“test.txt”实例
while ((str = bre.readLine())!= null) // 判断最后一行不存在,为空结束循环
{
pw.write(str );//将要写入文件的内容,写入到新文件
};
pw.close();//关闭流
bre .close();//关闭流
备注:文件流用完之后必须及时通过close方法关闭,否则会一直处于打开状态,直至程序停止,增加系统负担。
B. java 如何读取大文件
以下将从常规方法谈起,通过对比来说明应该如何使用java读取大文件。
1、常规:在内存中读取
读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法:
Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));
这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryError 异常。
例如:读取一个大约1G的文件:
@Test
public void givenUsingGuava_whenIteratingAFile_thenWorks() throws IOException {
String path = ...
Files.readLines(new File(path), Charsets.UTF_8);
}
这种方式开始时只占用很少的内存:(大约消耗了0Mb内存)
然而,当文件全部读到内存中后,我们最后可以看到(大约消耗了2GB内存):
这意味这一过程大约耗费了2.1GB的内存——原因很简单:现在文件的所有行都被存储在内存中。
把文件所有的内容都放在内存中很快会耗尽可用内存——不论实际可用内存有多大,这点是显而易见的。
此外,我们通常不需要把文件的所有行一次性地放入内存中——相反,我们只需要遍历文件的每一行,然后做相应的处理,处理完之后把它扔掉。所以,这正是我们将要做的——通过行迭代,而不是把所有行都放在内存中。
2、文件流
FileInputStream inputStream = null;
Scanner sc = null;
try {
inputStream = new FileInputStream(path);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
// System.out.println(line);
}
// note that Scanner suppresses exceptions
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
这种方案将会遍历文件中的所有行——允许对每一行进行处理,而不保持对它的引用。总之没有把它们存放在内存中:(大约消耗了150MB内存)
3、Apache Commons IO流
同样也可以使用Commons IO库实现,利用该库提供的自定义LineIterator:
LineIterator it = FileUtils.lineIterator(theFile, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
LineIterator.closeQuietly(it);
}
由于整个文件不是全部存放在内存中,这也就导致相当保守的内存消耗:(大约消耗了150MB内存)
C. java文件读写,在一个已经有内容的文件中,追加第一行,如何做到
我的想法是可以用RandomAccessFile,这个类的seek方法,想在文件的哪个位置插入内容都行。所以你的第一行就不在话下了。但是,这个会覆盖你文件中插入位置后面的内容。相当于我们在输入的时候,按了键盘的insert键盘。所以,像你这种情况只能用临时文件来存储原有的内容,然后把要插入的数据写入文件,再把临时文件的内容追加到文件中。x0dx0avoid insert(String filename,int pos,String insertContent){//pos是插入的位置x0dx0a File tmp = File.createTempFile("tmp",null);x0dx0a tmp.deleteOnExit();x0dx0a try{x0dx0a RandomAccessFile raf = new RandomAccessFile(filename,"rw");x0dx0a FileOutputStream tmpOut = new FileOutputStream(tmp);x0dx0a FileInputStream tmpIn = new FileInputStream(tmp);x0dx0a raf.seek(pos);//首先的话是0x0dx0a byte[] buf = new byte[64];x0dx0a int hasRead = 0;x0dx0a while((hasRead = raf.read(buf))>0){x0dx0a //把原有内容读入临时文件x0dx0a tmpOut.write(buf,0,hasRead);x0dx0a x0dx0a }x0dx0a raf.seek(pos);x0dx0a raf.write(insertContent.getBytes());x0dx0a //追加临时文件的内容x0dx0a while((hasRead = tmpIn.read(buf))>0){x0dx0a raf.write(buf,0,hasRead);x0dx0a }x0dx0a }x0dx0a}