面试题之——java交叉读取两个文件中单词,然后写入新的文件

来源:互联网 发布:steam免费mac游戏推荐 编辑:程序博客网 时间:2024/06/05 05:50

今天看到一道面试题,题目为:编写一个程序,将a.txt文件中的单词与b.txt文件中的单词进行交替合并到c.txt文件中 。a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格分开。

文章中给出的代码是

  1. import java.io.File;import java.io.FileReader;import java.io.FileWriter;public class MainClass {public static void main(String[] args) throws Exception {FileManager a = new FileManager("a.txt", new char[]{'\n'});FileManager b = new FileManager("b.txt", new char[]{'\n', ' '});FileWriter c = new FileWriter("c.txt");String aWord = null;String bWord = null;while((aWord=a.nextWord())!=null) {c.write(aWord + "\n");bWord = b.nextWord();if(bWord!=null) {c.write(bWord + "\n");}}while((bWord = b.nextWord())!=null) {c.write(bWord + "\n");}c.close();}}class FileManager {String[] words = null;int pos = 0;public FileManager(String filename, char[] seperators) throws Exception{File f = new File(filename);FileReader reader = new FileReader(f);char[] buf = new char[(int)f.length()];int len = reader.read(buf);String result = new String(buf, 0, len);String regex = null;if(seperators.length>1) {regex = "" + seperators[0] + "|" + seperators[1];} else {regex ="" + seperators[0];}words = result.split(regex);}public String nextWord() {if(pos == words.length) {return null;}return words[pos++];}}


代码不足之处

  代码本身能够做到题目的要求,但是有几处考虑不足:

  1. 在FileManager类中,我们使用FileReader字符流打开了资源,而在程序最后并没有关闭该资源,这是十分危险的操作。
  2. 在使用FileReader对文件进行读取时,只是简单的读取了一次就把读取到的数据封装成了String字符串。如果我们要读取的文件较小,只有几KB,那没有问题。那么,当我们读取的文件很大,大到一次并不能读取完,这是就出问题了。
  3. (这处也许是我多虑了)我们都知道,Linux和windows下的文件在回车换行方面处理不同。“\r,\n”都有新起一行的效果,但在两种操作系统中处理方式不同,也就是说,在windows下当我们敲下回车键时,在新起的上一行的最后会自动添加“\r\n”,而Linux下只会添加“\n”。此时就体现出了操作系统的差异性。那么我们对待这两种操作系统要有不同的操作。同时,在我们向新文件即c.txt文件中写入时,如果使用的是c.write(aWord + "\n");,那么在Windows下打开该文件,所有的单词应该显示成一行,而Linux操作系统下则会一个单词一个换行。

对上述不足改进

添加对资源进行关闭的方法

public void close() {if(fis!=null) {  //fis是读取文件的字节流try {fis.close();} catch (IOException e) {e.printStackTrace();} finally {fis = null;}}}

对读取文件内容进行改进

byte[] a = new byte[fis.available()];int len = fis.read(a);int total = 0;//如果total小于字节数组的长度,说明文件没有读取完成while (total < a.length) {total += len;//向字节数组中写入数据,起始偏移量是已读取数据长度, a.length - total表示剩余数据长度len = fis.read(a, total, a.length - total);}


改进后代码

package com.zyh.interview;import java.io.File;import java.io.FileInputStream;import java.io.FileWriter;import java.io.IOException;import java.net.URL;/** * 将a.txt文件中的单词与b.txt文件中的单词进行交替合并到c.txt文件中  * a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格分开 * @author zyh */public class Question111 {public static void main(String[] args) throws Exception {/**获取当前操作系统的换行符*/String lineSeparator = System.getProperty("line.separator");/**考虑到不同操作系统换行符的不同,Windows下是"\r\n",Linux下是"\n"(Unix下好像是"\r",不太确定)*/FileManager fma = new FileManager("a.txt", new String[]{"\n","\r\n"});/**"\\s"表示空格*/FileManager fmb = new FileManager("b.txt", new String[]{"\n","\r\n","\\s"});//c.txt文件保存位置是类路径即bin目录下FileWriter fw = new FileWriter(new File(ClassLoader.getSystemResource("").getFile(), "c.txt"));String aWord = null;String bWord = null;while((aWord=fma.nextWord())!=null) {                         //添加“A:”是为了观察容易结果是按怎样的顺序写入文件的                         fw.write("A:" + aWord + lineSeparator);if((bWord=fmb.nextWord())!=null) {fw.write("B:" +bWord+ lineSeparator);}}while((bWord=fmb.nextWord())!=null) {fw.write("B:" +bWord+ lineSeparator);}fw.flush();fw.close();/**关闭文件字符流对a.txt和b.txt资源的连接*/fma.close();fmb.close();}}class FileManager {String[] words = null;int pos = 0;FileInputStream fis = null;public FileManager() {}public FileManager(String fileName, String[] seperators) throws Exception {/**获取当前项目的类路径*/URL classpath = FileManager.class.getClassLoader().getResource("");File file = new File(classpath.getFile(), fileName);fis = new FileInputStream(file);/**从文件中读取数据*/byte[] a = new byte[fis.available()];int len = fis.read(a);int total = 0;//如果total小于字节数组的长度,说明文件没有读取完成while (total < a.length) {total += len;//向字节数组中写入数据,起始偏移量是已读取数据长度, a.length - total表示剩余数据长度len = fis.read(a, total, a.length - total);}StringBuffer regex = new StringBuffer();for(String seperator : seperators){regex.append(seperator + "|");}regex.deleteCharAt(regex.length()-1);words = new String(a).split(regex.toString());}public String nextWord(){if(pos >= words.length) {return null;}return words[pos++];}public void close() {if(fis!=null) {try {fis.close();} catch (IOException e) {e.printStackTrace();} finally {fis = null;}}}}

结果示例

从左到右文件名依次为:b.txt, a.txt, c.txt(c.txt并未显示完结果)



原创粉丝点击