Двумерные массивы, работа с файлами и исключения в Java


В этой небольшой статье я познакомлю вас с двумерными массивами, чтением и записью файлов, а также с исключениями на языке Java. Информации будет достаточно для реализации практических и курсовых работ начальной и средней сложности.



Двумерный массив

Двумерный массив в Java есть не что иное как массив одномерных массивов. Элементы двумерных массивов соответственно индексируются парой индексов – каждый записывают в отдельных квадратных скобках. Общая форма объявления двумерного массива:

<тип элементов> <название массива>[<размерность1>][<размерность2>]; 
Как и в случае одномерного массива, разрешается записывать размерность массива сразу и после типа элементов. Примеры объявления двухмерных массивов:

int[][]A=new int[5][5];
floatB[][] =new float[3][2];
Для обработки двумерных массивов используют вложенные циклы for, например:

int max=A[1][1];
for(inti=0;i<5;i++)
	for(intj=0;j<5;j++)
		if(max<A[i][j])
			max=A[i][j];
Разрешается также инициализация двумерного массива элементами при описании, например:

int[][]A={
{5, 6, 1, 3},
{3, 4, 2, 1},
{1, 2, 2, 2}
};
Для чтения данных из текстового файла можно использовать класс BufferedReader, как и для считывания данных из консоли. Для этого его следует инициализировать представителем класса FileReader, который, в свою очередь, конструируется на основе объекта класса File:

BufferedReader input = new BufferedReader(new FileReader(new File("data.txt")));
Но такой способ предполагает использование методов read() или readLine(), которыми сложно обрабатывать текстовые ленты, содержащие по несколько числовых данных. Еще более удобным в таковых вариантах является внедрение класса java.util.Scanner, имеющего способ hasNext() для проверки того есть ли во входящем потоке еще одна порция данных. В случае ввода целых чисел используют метод hasNextInt() (для действительных hasNextFloat(), hasNextDouble()). Если следующая порция данных есть, то ее можно прочесть методами next(), nextInt() (nextFloat, nextDouble), соответственно.

Организовать такой ввод данных можно аналогично предыдущему:

Scanner input = new Scanner(new FileReader(new File("data.txt")));
Для записи данных используют поток вывода являющийся экземпляром класса PrintWriter. Этот объект взаимодействует с потоком вывода в файл типа FileWriter через соответствующий буфер BufferedWriter. К примеру:

File fB = new File("D:\\B.txt");
FileWriter fileWrite = новый FileWriter(fB);
BufferedWriter writeBufer = новый BufferedWriter(fileWrite);
PrintWriter printB = New PrintWriter(writeBufer);
Или короче с использованием анонимных объектов:

FileWriter fileWrite = new FileWriter(new File("D:\\B.txt"));
PrintWriter printB = New PrintWriter(New BufferedWriter(fileWrite));
При этом можно использовать те же методы print(), println(), printf(), format(), что и при выводе данных на консоль.

Ошибки и обработка исключений

Считывание данных из файлов – процесс при котором часто могут возникать ошибки, например отсутствие файла с данными, или неправильная запись данных в файле. В классических языках программирования, например, в С, приходилось проверять какое-либо условие, указывающее на наличие ошибки, и в зависимости от этого совершать те или иные действия. В Java появилось более простое решение – обработка исключительных ситуаций.

try{
someAction();
anotherAction();
} catch(Exception e) {
// обработка исключения
}
При возникновении исключительной ситуации управление передается от кода, вызвавшего исключительную ситуацию, на ближайший блок catch (или вверх по стеку) и создается объект, унаследованный от класса Throwable, или его потомков, содержащий информацию об исключительной ситуации и используемой при ее обработке. По сути, в блоке catch указывается именно класс обрабатываемой ситуации.

Допускается создание собственных классов исключительных ситуаций. Осуществляется это посредством механизма наследования, т.е. класс исключительной ситуации, созданный пользователем должен быть унаследован от класса Throwable или его потомков. Конструкция try-catch в общем случае выглядит так:

try {
...
} catch(SomeExceptionClass e) {
...
} catch(AnotherExceptionClass e) {
...
}
Сначала выполняется код в фигурных скобках после оператора try. Если во время его выполнения не происходит никаких внештатных ситуаций, то управление передается за закрывающую фигурную скобку последнего оператора catch, ассоциированного с данным оператором try. Если в пределах try возникает исключительная ситуация, то далее выполнение кода производится по одному из следующих сценариев: Конструкция try-catch в общем случае выглядит так:

  • Если возникла исключительная ситуация, класс которой указан как параметр одного из блоков catch, выполняется блок кода, ассоциированный с данным catch. Далее, если код в этом блоке завершается нормально, то весь оператор try завершается нормально и управление передается на оператор после закрывающей фигурной скобки последнего catch.
  • Если код в catch завершается некорректно, то весь try завершается некорректно по той же причине.
  • Если возникла исключительная ситуация, класс которой не указан в качестве довода ни в одном catch, то выполнение всего try завершается некорректно.
Конструкция try-catch-finally позволяет с помощью оператора finally гарантировать выполнение любого фрагмента кода, независимо от того, возникла исключительная ситуация или нет. Последовательность выполнения такой конструкции следующая:

  • если оператор try выполнен нормально, то будет исполнен блок finally. В свою очередь, если оператор finally выполняется нормально, то весь оператор try выполняется нормально.
  • Если во время выполнения блока try возникает исключение и существует оператор catch, перехватывающий данный тип исключения, происходит выполнение связанного с блоком catch.
  • Если блок catch выполняется нормально или ненормально, все равно затем выполняется блок finally. Если блок finally завершается нормально, оператор try завершается так же, как завершился блок catch.
  • Если в списке операторов catch не находится такого, которое обработало бы возникшее исключение, то все равно выполняется блок finally. В этом случае, если finally завершится нормально, весь try завершится ненормально по той же причине, по которой было нарушено исполнение try.
Во всех случаях, если блок finally завершается ненормально, весь try завершится ненормально по той же причине.

try {
byte[] buffer = new byte[128];
FileInputStream fis = new FileInputStream("file.txt");
while(fis.read(buffer) > 0) {
... обработка данных ...
}
} catch(IOException es) {
... обработка исключения ...
} finally {
fis.flush();
fis.close();
}
Если в данном примере поместить операторы очистки буфера и закрытия файла сразу после окончания обработки данных, то при возникновении ошибки ввода/вывода корректного закрытия файла не произойдет.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, java, массивы, файлы, обработка исключений




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Идентичность и равенство объектов в Java
Урок 21. Логические операторы JavaScript
Изменение размера массивов