如何从文本文件的下一行读取并暂停,允许我稍后阅读该行?

时间:2015-07-18 03:36:56

标签: java bufferedreader filereader printwriter bufferedwriter

我写了一个程序,根据两个常量文件,将随机数生成两个文本文件,随机写入三分之一。现在我需要逐行读取每个文本文件,并将它们放在一起。该计划是here找到的建议对我的情况没有任何帮助。当我尝试这种方法时,它只读取所有行,直到它完成而不允许我暂停它,转到不同的文件等选项。

理想情况下,我想找到一些方法来阅读下一行,然后再去那行。就像某种变量可以让我在阅读中占有一席之地。

public static void mergeProductCodesToFile(String prefixFile,
                                           String inlineFile,
                                           String suffixFile,
                                           String productFile) throws IOException 
{
    try (BufferedReader br = new BufferedReader(new FileReader(prefixFile))) 
    {
        String line;
        while ((line = br.readLine()) != null) 
            {
                try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(productFile, true))))
                {
                        out.print(line); //This will print the next digit to the right
                }
            catch (FileNotFoundException e) 
                {
                    System.err.println("File error: " + e.getMessage());
                }  
            }
    }
}

编辑:根据以下内容创建的数字。基本上,常量告诉它要在每行中创建多少位数以及要创建多少行。现在我需要将这些组合在一起而不删除任何文本文件中的任何内容。

public static void writeRandomCodesToFile(String codeFile, 
                                          char fromChar, char toChar,
                                          int numberOfCharactersPerCode,
                                          int numberOfCodesToGenerate) throws IOException 
{

    for (int i = 1; i <= PRODUCT_COUNT; i++)
    {
        int I = 0;


        if (codeFile == "inline.txt")
        {

            for (I = 1; I <= CHARACTERS_PER_CODE; I++)
            {
                int digit = (int)(Math.random() * 10);


                try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
                {
                        out.print(digit); //This will print the next digit to the right
                }
                catch (FileNotFoundException e) 
            {
                System.err.println("File error: " + e.getMessage());
                System.exit(1);  
            }

            }
        }

        if ((codeFile == "prefix.txt") || (codeFile == "suffix.txt"))
        {

            for (I = 1; I <= CHARACTERS_PER_CODE; I++)
            {
                Random r = new Random();
                char digit = (char)(r.nextInt(26) + 'a');
                digit = Character.toUpperCase(digit);

                try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
                {
                        out.print(digit);
                }
                catch (FileNotFoundException e) 
            {
                System.err.println("File error: " + e.getMessage());
                System.exit(1);  
            }

            }    
        }
            //This will take the text file to the next line
            if (I >= CHARACTERS_PER_CODE)
            {
                {
                Random r = new Random();
                char digit = (char)(r.nextInt(26) + 'a');

                try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
                {
                        out.println(""); //This will return a new line for the next loop
                }
                catch (FileNotFoundException e) 
            {
                System.err.println("File error: " + e.getMessage());
                System.exit(1);  
            }
                }
            }

    }
    System.out.println(codeFile + " was successfully created.");

}// end writeRandomCodesToFile()

2 个答案:

答案 0 :(得分:1)

尊重您的代码,它将是这样的:

public static void mergeProductCodesToFile(String prefixFile, String inlineFile, String suffixFile, String productFile) throws IOException {
    try (BufferedReader prefixReader = new BufferedReader(new FileReader(prefixFile));
        BufferedReader inlineReader = new BufferedReader(new FileReader(inlineFile));
        BufferedReader suffixReader = new BufferedReader(new FileReader(suffixFile))) {

      StringBuilder line = new StringBuilder();
      String prefix, inline, suffix;
      while ((prefix = prefixReader.readLine()) != null) {
        //assuming that nothing fails and the files are equals in # of lines.
        inline = inlineReader.readLine();
        suffix = suffixReader.readLine();
        line.append(prefix).append(inline).append(suffix).append("\r\n");
        // write it
        ...

      }
    } finally {/*close writers*/}
  }

可能会抛出一些例外。

我希望你不要在一个方法中实现它。 您也可以使用迭代器,或者非常简单的读者类(方法)。

我不会使用List来加载数据至少我保证文件的大小很小,我可以节省内存使用量。

答案 1 :(得分:1)

我们通过存储数据和交错来讨论我的方法。就像塞尔吉奥在他的回答中所说,确保内存在文件大小和数据结构将使用多少内存方面不是问题。

//the main method we're working on
public static void mergeProductCodesToFile(String prefixFile,
                                       String inlineFile,
                                       String suffixFile,
                                       String productFile) throws IOException
{
    try {
        List<String> prefix = read(prefixFile);
        List<String> inline = read(inlineFile);
        List<String> suffix = read(productFile);

        String fileText = interleave(prefix, inline, suffix);
        //write the single string to file however you want
    } catch (...) {...}//do your error handling...
}

//helper methods and some static variables
private static Scanner reader;//I just prefer scanner. Use whatever you want.
private static StringBuilder sb;

private static List<String> read(String filename) throws IOException
{
    List<String> list = new ArrayList<String>;
    try (reader = new Scanner(new File(filename)))
    {
        while(reader.hasNext())
        { list.add(reader.nextLine()); }
    } catch (...) {...}//catch errors...
}

//I'm going to build the whole file in one string, but you could also have this method return one line at a time (something like an iterator) and output it to the file to avoid creating the massive string
private static String interleave(List<String> one, List<String> two, List<String> three)
{
    sb = new StringBuilder();
    for (int i = 0; i < one.size(); i++)//notice no checking on size equality of words or the lists. you might want this
    {
        sb.append(one.get(i)).append(two.get(i)).append(three.get(i)).append("\n");
    }
    return sb.toString()
}

显然,在内存和性能方面仍有一些需要;此外,还有一些方法可以使其在其他情况下更具可扩展性,但这是一个很好的起点。使用c#,我可以更轻松地使用迭代器使交错一次为您提供一行,从而可能节省内存。只是一个不同的想法!