【问题标题】:A Good Method to read files in JavaJava中读取文件的好方法
【发布时间】:2013-02-28 21:11:34
【问题描述】:

如果有人可以帮助我,我将不胜感激。我正在尝试进行外部排序,但我陷入了合并的困境。我知道我应该如何合并它只是不确定要使用什么功能。

现在我正在尝试读取多个小文本文件的第一个单词,并将它们存储在文件数量大小的字符串数组中。所以基本上我会有一个每个文件的第一个单词的字符串数组。然后我根据字母顺序确定哪个是最小的并将其写入一个新文件,之后我将读取该最小单词的文件的下一个单词。该单词将放置在字符串数组中输出的最小单词的位置,并将其与其他文件中第一个单词的其余部分进行比较。这将不断重复,直到所有单词都被排序。

我遇到的主要问题是我正在使用扫描仪,并且在第一次比较它之后无法将最小的单词与文件中的下一个单词切换,因为扫描仪没有保留它所拥有的内容读。我知道 readline 可以,但是由于我的文件都是由空格分隔的所有单词,因此我不能使用 readline。有人可以指导我使用无法帮助我解决此问题的足够阅读功能。

  for (int i = 0; i<B;i++)
  {
  try
  {
    BufferedReader ins = new BufferedReader(new FileReader(Run-"+ i + ".txt"));
    Scanner scanner2 = new Scanner(ins);
    temp3[i] = scanner2.next();

                System.out.println(temp3[i]);
            }
            catch(IOException e)
            {   
            }
        }
        for(int i=0;i<N;i++)
        {
            String smallest = temp3[0];
            int smallestfile = 0;
            for(j=0;j<B;j++)
            {
                int comparisonResult = smallest.compareTo(temp3[j]);
                if(comparisonResult>0)
                {
                smallest = temp3[j];
                smallestfile = j;
                }
            }
            BufferedReader ins = new BufferedReader(new FileReader("C:/Run-"+ smallestfile + ".txt"));
            Scanner scanner2 = new Scanner(ins);
            if(scanner2.hasNext())
            {
                temp3[smallestfile]=scanner2.next();
            }
        }
}
catch(Exception e)
{
}

【问题讨论】:

  • 哦,请格式​​化这一段,分成多段。我很难读到这篇文章,抱歉。
  • 对不起,我有点重新格式化该段落。只是我真的需要这样做,我真的被困在这部分了。
  • 所有文件都只有一行吗?
  • 基本上是的。因为当我对它进行排序时,我所做的只是在每个单词之间添加一个空格。

标签: java string file-io merge


【解决方案1】:

如果文件足够小,则将整个文件读入内存,并使用String.split() 将字符串分隔为数组并发挥作用。

如果文件较大,请保持打开并读取每个字节,直到找到并留出空间,然后对所有文件执行此操作,比较字符串,施展你的魔法并重复直到所有文件到达末尾。

编辑:

  • 如何用BufferedReader读取文件
  • 如何用 String.split() 分割行

String line = readeOneLineFromTheCurrentFile(); String[] words = line.split(" ");

【讨论】:

  • 如果你有时间可以请你写一个简单的例子给我。我的大脑现在真的被炸了。
  • 如果您没有时间,您不必这样做。我完全明白。我不想让自己看起来要求太多。
  • 几乎睡在键盘上 :) 只需在 cmets 中添加一些小块,希望它能指导!
  • 感谢您的帮助。我真的很感激。
  • 我只希望扫描仪实际上使用指针,以便它也知道它在哪里读取。
【解决方案2】:

至于临时排序/存储单词,请使用PriorityQueue(不是数组)。抱歉,我忙着看棒球,无法添加更多内容。

【讨论】:

  • 感谢您的评论。通过使用字符串数组,我已经让排序部分工作了。我真的只需要完成这部分。不过非常感谢。
【解决方案3】:

我不确定我是否理解正确,但Scanner 确实将位置保留在文件中。您需要的文件数量与文件数量一样多

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class so {
    // returns the index of the smallest word
    // returns -1 if there are no more words
    private static int smallest(String[] words) {
        int min = -1;
        for (int i = 0; i < words.length; ++i)
            if (words[i] != null) {
                if (min == -1 || words[i].compareTo(words[min]) < 0)
                    min = i;
            }

        return min;
    }

    public static void main(String[] args) throws FileNotFoundException {
        // open all files
        Scanner[] files = new Scanner[args.length];
        for (int i = 0; i < args.length; ++i) {
            File f = new File(args[i]);
            files[i] = new Scanner(f);
        }

        // initialize first words
        String[] first = new String[args.length];
        for (int i = 0; i < args.length; ++i)
            first[i] = files[i].next();

        // compare words and read following words from scanners
        int min = smallest(first);
        while (min >= 0) {
            System.out.println(first[min]);
            if (files[min].hasNext()) {
                first[min] = files[min].next();
            } else {
                first[min] = null;
                files[min].close();
                files[min] = null;
            }

            min = smallest(first);
        }
    }
}

经过测试

a.txt:a d g j
b.txt:b e h k m
c.txt:c f i

更新

在您的示例中,您在外部 for 循环中打开和关闭文件。当您下次重新打开文件时,它当然会从文件的开头开始。

为防止这种情况,您必须保持文件打开并将scanner2 变量及其初始化移到外部for 循环的前面。您还需要多个Scanner 变量,即一个数组,以保持多个文件同时打开。

【讨论】:

  • 我明白你在这里的意思,但是当我尝试它之前它不起作用。假设我有 3 个文件,每个文件包含 3 个单词。我从每个文件中取出第一个单词并进行比较。当我找到与 3 相比最小的那个时,我打印出那个单词,然后从那个文件中我想读入下一个出现的单词。当我使用扫描仪时,它会一直给我返回与文件中第一个单词相同的单词。
  • @user2163684 这不应该发生,因为Scanner.next 说“Throws: NoSuchElementException - 如果没有更多可用的令牌”。
  • @user2163684 我不想把所有的乐趣都拿出来,但是请看完整的例子。
  • 非常感谢您的帮助!!我只是上传了我的代码版本,如果负担不大的话,你能看看它有什么不按预期的方式工作吗?
  • 非常感谢。我要去看看它。无论如何,如果我需要进一步的帮助,我可以与您联系。如果你不介意的话。
猜你喜欢
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
相关资源
最近更新 更多