简体   繁体   中英

How can I read from the next line of a text file, and pause, allowing me to read from the line after that later?

I wrote a program that generates random numbers into two text files and random letters into a third according the two constant files. Now I need to read from each text file, line by line, and put them together. The program is that the suggestion found here doesn't really help my situation. When I try that approach it just reads all lines until it's done without allowing me the option to pause it, go to a different file, etc.

Ideally I would like to find some way to read just the next line, and then later go to the line after that. Like maybe some kind of variable to hold my place in reading or something.

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

EDIT : The digits being created according to the following. Basically, constants tell it how many digits to create in each line and how many lines to create. Now I need to combine these together without deleting anything from either text file.

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

Being respectfull with your code, it will be something like this:

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*/}
  }

Some exceptions may be thrown.

I hope you don't implement it in one single method. You can make use of iterators too, or a very simple reader class (method).

I wouldn't use List to load the data at least I guarantee that the files will be low sized and that I can spare the memory usage.

My approach as we discussed by storing the data and interleaving it. Like Sergio said in his answer, make sure memory isn't a problem in terms of the size of the file and how much memory the data structures will use.

//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()
}

Obviously there is still some to be desired in terms of memory and performance; additionally there are ways to make this slightly more extensible to other situations, but it's a good starting point. With c#, I could more easily make use of the iterator to make interleave give you one line at a time, potentially saving memory. Just a different idea!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM