Kodomo

Пользователь

Учебная страница курса биоинформатики,
год поступления 2010

Файлы, строки, обработка исключений

Часто бывает необходимо разработать программу обрабатывающую большой объем данных или создающую данные в таком объеме. Часто очень удобным решением этой проблемы является хранение данных в файлах. В Java имеется класс File (java.io.*), объекты которого предоставляют информацию о файлах и директориях и простые операции над ними, такие как проверка на существование, удаление, создание пустого файла, проверка защиты от записи, информация о времени создания/модификации, получение списка файлов в директории:

   1 File f = new File(“C:\\Windows\\system32\\kernel32.dll”);
   2 if(!f.exists()) {
   3         S.o.p.(“Странная винда”);
   4 } 
   5 else if(!f.canWrite()) {
   6         S.o.p.(“Ресурс защищен”);
   7 }
   8 else f.delete();

Байтовые потоки.

Если нам необходимо работать с содержимым файла как с набором байтов, то можно считывать и записывать данные, используя байтовые потоки.

   1 InputStream is = new FileInputStream(“test.bmp”);
   2 OutputStream os = new FileOutputStream(“clone.bmp”);
   3 for(;;) {
   4         int num = is.read();
   5         if(num<0) break;
   6         os.write(num);
   7 }
   8 is.close();
   9 os.close();

Текстовые потоки.

Но часто необходимо работать с данными в файлах как с набором текстовых строк. Для этого используют текстовые потоки FileReader и FileWriter. Чтобы иметь возможность считывать текст построчно, используют оболочку BufferedReader.

   1 BufferedReader br = new BufferedReader(new FileReader(f));
   2 for(int line_num=1;;line_num++) {
   3         String line = br.readLine();
   4         if(line==null) break;
   5         S.o.p.(“Line “+line_num+”: “+line);
   6 }
   7 br.close();

Чтобы работать с файлом также как с консолью используют оболочку PrintWriter:

   1 Reader r = new FileReader(“text.txt”);
   2 PrintWriter w = new PrintWriter(new FileWriter(“new_text.txt”));
   3 w.println(“Этот текст есть результат удаления пробелов из исходного варианта:”);
   4 w.println();
   5 for(;;) {
   6         int symbol = r.read();
   7         if(symbol<0) break;
   8         char ch = (char)symbol;
   9         if(ch!=’ ‘) {
  10 System.out.print(ch);
  11 w.write(symbol);
  12         }
  13 }
  14 r.close();
  15 w.close();

Строки.

Для хранения строк используется класс Public final class String Обратите внимание, что этот класс final. Это означает, что объекты этого класса не могут быть изменены (нельзя изменять строку в объекте, заменять отдельные символы и т.п.). Основные конструкторы:

   1 public String() и public String (byte[]);

Основные методы:

метод

описание

public char charAt(int i)

Возвращает i-й символ строки

public String concat(String str)

Возвращает строку, являющейся объединением данной строки и строки str

public boolean endsWith(String suffix)

Возвращает true, если строка заканчивается на suffix

public boolean startsWith(String prefix)

Возвращает true, если строка начинается на prefix

public boolean equals(Object anObject)

Возвращает true, если данная строка по буквенной последовательности совпадает со строкой anObject

public boolean equalsIgnoreCase(String anotherString)

Возвращает true, если данная строка по буквенной последовательности совпадает со строкой anotherString без учета регистра

public int indexOf(int ch)

Возвращает позицию первого вхождения символа ch в строку. Если нет вхождения, -1

public int indexOf(String str)

Возвращает позицию первого вхождения подстроки str в строку. Если нет вхождения, -1

public int lastIndexOf(int ch)

Возвращает позицию последнего вхождения символа ch в строку. Если нет вхождения, -1

public int lastIndexOf(String str)

Возвращает позицию последнего вхождения подстроки str в строку. Если нет вхождения, -1

public int length()

Возвращает длину слова

public boolean matches(String regex)

Возвращает true, если слово удовлетворяет регулярному выражению

public String[] split(String regex)

Разбивает строку на подстроки по разделителю, удовлетворяющему регулярному выражению.

public String substring(int beginIndex, int endIndex)

Возвращает подстроку, начиная с позиции beginIndex по позицию endIndex-1 включительно

public String toLowerCase()

Возвращает строку, полученную из данной приведением всех символов к нижнему регистру

public String toUpperCase()

Возвращает строку, полученную из данной приведением всех символов к верхнему регистру

public String trim()

Возвращает строку, полученную из данной путем удаления концевых пробельных символов

public byte[] getBytes()

Возвращает массив байтов (символов) данной строки

Разбор строки.

Иногда в строках текстового файла лежат данные в структурированном виде. Если строки включают числа или слова, разделенные специальными символами, то для их выделения мы можем использовать стандартный класс StringTokenizer:

   1 BufferedReader br = new BufferedReader(new FileReader(f));
   2 double mid_x = 0;
   3 double mid_y = 0;
   4 int qnt = 0;
   5 for(;;) {
   6         String line = br.readLine();
   7         if(line==null) break;
   8         StringTokenizer st = new StringTokenizer(line,” \t”);
   9         if(st.countTokens()!=2) throw new Exception(“Должно быть два числа !”);
  10         String x_num = st.nextToken();
  11         double x = Double.parseDouble(x_num);
  12         String y_num = st.nextToken();
  13         double y = Double.parseDouble(y_num);
  14         mid_x += x;
  15         mid_y += y;
  16         qnt++;
  17 }
  18 br.close();
  19 mid_x /= qnt;
  20 mid_y /= qnt;
  21 S.o.p.(“Центр тяжести: (“+mid_x+”;”+mid_y+”)”);

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

Иногда бывает так, что ваш код написан правильно, но при его выполнении может произойти что-то неожиданное. Например вы попробуете поделить на 0. Или пока вы файл читали, его кто-то злонамеренно стер. В тот момент когда java машина попробует сделать что-то невозможное (поделить на 0, или прочитать несуществующий файл) она выбросит ошибку (ошибка — это объект наследующий класс Exception) и прервет исполнение программы. Некоторые методы заранее знают что при их выполнении может быть ошибка, это прописано в их названии при помощи ключевого слова throws Exception. Например метод readLine() в классе BufferedReader имеет следующее объявление:

   1 public String readLine() throws IOException

что означает что этот метод может выбросить ошибку типа IOException — ошибка ввода-вывода, класс IOException наследует Exception. Поскольку заранее известна возможность появления ошибки, то вам надо заранее позаботиться о ее обработке. Это можно сделать двумя способами. Во-первых — можно вовсе ее не обрабатывать, а просто сказать что ваш метод — в котором вы все пишете, например в main, тоже выбрасывает ошибку:

   1 public static void main(String[] args) throws IOException {
   2         BufferedReader b = new  BufferedReader(new FileReader("file"));
   3         String l = b.readLine();
   4         b.close();
   5         System.out.println(l);
   6         System.out.println("Bye");
   7 }

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

   1 try{
   2         //сделать что-нибудь, что может выкинуть ошибку типа XException
   3 }catch(XException e){
   4         //сделать что-то с этой ошибкой
   5 }
   6 //продолжить выполнение
   7 

Исправим ситуацию:

   1 public static void main(String[] args){
   2         try{
   3                 BufferedReader b = new  BufferedReader(new FileReader("file"));
   4                 String l = b.readLine();
   5                 b.close();
   6                 System.out.println(l);
   7         }catch(IOException e){
   8                 System.out.println("Somthing wrong with file 'file'");
   9                 e.printStackTrace();
  10         }
  11         System.out.println("Bye");
  12 }