Я пишу программу в Java, который требует, чтобы я сравнил данные в 2 файлах. Я должен проверить каждую строку из файла 1 против каждой строки файла 2 и если я нахожу, что соответствие пишет им в третий файл. После того, как я читал в конец файла 2, как я сбрасываю указатель на начало файла?
public class FiFo {
public static void main(String[] args)
{
FileReader file1=new FileReader("d:\\testfiles\\FILE1.txt");
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
try{
String s1,s2;
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
}
}
file1.closeFile();
file2.closeFile();
}catch (IOException e) {
e.printStackTrace();
}
}
}
class FileReader {
BufferedReader data;
DataInputStream in;
public FileReader(String fileName)
{
try{
FileInputStream fstream = new FileInputStream(fileName);
data = new BufferedReader(new InputStreamReader(fstream));
}
catch (IOException e) {
e.printStackTrace();
}
}
public void closeFile()
{
try{
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Я полагаю, что Случайный файл
- это то, что вам нужно. Он содержит: RandomAccessFile#seek
and RandomAccessFile#getFilePointer
.
rewind()
is seek(0)
Я думаю, что лучше всего было бы поместить каждую строку из файла 1 в HashMap
; тогда вы могли бы проверять каждую строку файла 2 на принадлежность к вашей HashMap
, вместо того, чтобы читать весь файл один раз для каждой строки файла 1.
Но чтобы ответить на вопрос, как вернуться к началу файла, проще всего открыть другой InputStream
/Reader
.
Очевидно, что можно просто закрыть и снова открыть файл вот так:
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
//compare s1 and s2;
}
file2.closeFile()
}
Но Вы действительно не хотите делать это таким образом, так как время работы этого алгоритма - O(n2). Если бы в файле A было 1000 строк, а в файле B - 10000 строк, Ваш внутренний цикл прошел бы 1,000,000 раз.
Что вам нужно сделать, так это прочитать каждую строку и сохранить ее в коллекции, которая позволяет быстро проверить, не содержится ли уже элемент (возможно, это HashSet).
Если вам нужно только проверить, что каждая строка в файле 2 находится в файле 1, то вы просто добавляете каждую строку в файле 1 в HashSet, а затем проверяете, что каждая строка в файле 2 находится в этом наборе.
Если вам нужно провести перекрестное сравнение, где вы найдете каждую строку, которая находится в одной, но не в другой, то вам понадобится два набора хэшей, по одному для каждого файла. (Хотя есть одна хитрость, которую Вы можете сделать, чтобы использовать только один)
Если файлы настолько велики, что у Вас недостаточно памяти, то Ваш оригинальный метод n2 все равно бы никогда не сработал.
Как предлагали другие, следует рассмотреть другие подходы к проблеме. Для конкретного вопроса возвращения к предыдущей точке в файле, java.io.FileReader
наследует mark()
и reset()
методы, которые решают эту задачу.
ну, Геннадий С. вот что я бы использовал для решения вашей проблемы.
Я пишу программу на Java, которая требует сравнить данные в двух файлах
однако, я бы предпочел не кодировать это снова... Я бы предпочел использовать что-то вроде http://code.google.com/p/java-diff-utils/
Небольшой вопрос. Не можете ли вы держать один объект в начале файла и перемещаться по файлу с другим объектом? Затем, когда вы доберетесь до конца, просто направьте его на объект в начале файла (потока). Я полагаю, что в C++ есть такие механизмы с файловым вводом/выводом (или потоковым вводом/выводом)
Как уже отмечалось, есть лучшие алгоритмы - исследуйте эти
в стороне:
FileReader не поддерживает отметку и сброс, поэтому комментарии trashgod неточны. {{1} } Вам придется либо реализовать версию этого (используя RandomAccessFile или что-то еще), либо обернуть в BufferedReader. Однако последний загрузит все это в память, если вы отметите его