#java #sorting #while-loop #ioexception
#java #сортировка #цикл while #ioexception
Вопрос:
Я пытаюсь использовать пузырьковую сортировку (я знаю, что она очень неэффективна) для сортировки некоторых данных, но мой код ведет себя довольно странно, после ровно 926 проходов внешнего цикла while выдается исключение IOException, это не зависит от введенных данных, я проверил, и, похоже, это не так.код и исключение, связанные с объемом доступной памяти, приведены ниже:
public static void sort(String f1, String f2) throws FileNotFoundException, IOException {
RandomAccessFile reader = new RandomAccessFile(f1,"rw");
RandomAccessFile writer = new RandomAccessFile(f1,"rw");
// start the bubble sort
int limit = (int) reader.length()/4;
while (limit>1) {
DataOutputStream writerstream = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(writer.getFD())));
DataInputStream readerstream = new DataInputStream(
new BufferedInputStream(new FileInputStream(reader.getFD())));
// the first value, a is the first value in the file
int a = readerstream.readInt();
int myfilepointer = 4;
// this flag is used to stop passing through when correct order is detected
boolean setpass = false;
// pass through the file
while (myfilepointer<limit*4) {
// the second value, b is the next value in the file
//System.out.println(myfilepointer);
int b = readerstream.readInt();
myfilepointer = 4;
// test if a and b are in the correct way around
// if wrong way around then b is written and the next a value is the same as before
if (a>b) { writerstream.writeInt(b); setpass = false; }
// if the correct way about then a is written and the next a value is the same as the previous b value
else { writerstream.writeInt(a); a = b; }
}
// this last value is the a value of exiting the while loop
writerstream.writeInt(a);
// write the new data to the file
writerstream.flush();
writer.seek(0);
reader.seek(0);
// if there was no swaps then the order is correct so exit loop
if (setpass == true) break;
limit -= 1;
}
}
и генерируемое исключение приведено ниже
Exception in thread "main" java.io.IOException: Read error
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readInt(Unknown Source)
at uk.ac.cam.hh360.fjava.tick0.ExternalSort.sort(ExternalSort.java:48)
at uk.ac.cam.hh360.fjava.tick0.ExternalSort.main(ExternalSort.java:119)
Комментарии:
1. Почему вы создаете два экземпляра RandomAccessFile ? Зачем использовать объекты DataInputSource?
Ответ №1:
Одна из потенциальных проблем заключается в том, что вы не закрываете потоки, открытые во внешнем цикле.
Комментарии:
1. Я попытался закрыть потоки с помощью readerstream.close(), но это также закрывает объект reader
Ответ №2:
Вы записываете в тот же файл, который читаете. Итак, как только вы записываете свое первое целое число в поток записи, содержимое файла заменяется тем, что вы написали. Поскольку вы используете BufferedOutputStream, на самом деле это может произойти позже, чем при первой записи.
Вы должны прочитать все целые числа в памяти, закрыть входной поток, отсортировать целые числа в памяти, а затем записать все целые числа в файл.
Я не понимаю, почему вы используете файл произвольного доступа только для получения дескриптора файла и открытых потоков в файле. Либо вы хотите получить к нему случайный доступ, либо вы хотите получить к нему доступ с помощью потоков. Но вы не можете сделать и то, и другое.
Комментарии:
1. Я изо всех сил пытался создать этот метод, используя более сложный метод, поэтому мне сказали начать с пузырьковой сортировки и использования RandomAccessFile, чтобы затем его можно было легко улучшить и изменить
2. Вы ничего не делаете с файлами произвольного доступа, кроме поиска 0. Вы читаете и записываете с использованием потоков.