Java: Засоби побудови звітів для Java-додатків h2>
Дмитро Левиков p>
Це
короткий огляд засобів побудови звітів для Java-додатків. Я спробував
отримати демо-версію кожного з них і побудувати звіт певного виду, зв'язавши
його з програмою на мові Java. Якщо Вам відомо будь-що окрім того, що я
тут понаписали, напишіть мені, внесені вами зміни будуть до речі. І так ... p>
Enterprise b>
b> Reports b> ( b> TM b> ) b> for b> b> Java b> p>
Короткий
опис: p>
Продукт
повністю реалізований на Java. Джерелами даних можуть бути JDBC-сумісні
джерела, Java-класи та EJB. p>
Можливості:
p>
Extract
Data - ERW може отримувати дані з традиційної бази даних або з програми.
ERW використовує JDBC або ODBC для отримання даних з БД. Для даних програми,
ERW надає зручний механізм для визначення структур класів програми
та завантаження даних через них. Надання даних з програм швидше,
масштабування ідеально підходить для розподілених додатків. p>
Analyze
Data - ERW надає такі можливості як: багато секційні,
перехресні таблиці (crosstabs), діаграми/графіки, формули і Зміст
(Table of Contents). ERW Report Engine дозволяє будувати звіти в реальному
часу p>
Format
Data - ERW надає простий у використанні дизайнер звітів з широким
набором средст форматування як шрифти, кольори, вирівнювання, перенесення, розрив
сторінок, що перекриваються, компоненти і т.д. p>
Output
Data - ERW може експортувати будь-який звіт у PDF, HTML, Hi-Res HTML, або
ASCII-CSV p>
Ціни p>
Версія p>
Ціна p>
ERW 4.0 Pro (Includes both AWT & Swing
versions) p>
$ 495 p>
Підписка на рік p>
$ 995 p>
Limited Free Runtime (100
копій) p>
Додається p>
URL:
http://www.enterprisesoft.com/Products/ReportWriter.html p>
Примітка:
p>
З
випробуваних продуктів Enterprise Reports має найбільш зручний дизайнер
звітів з дуже багатим набором функцій. Розміщення і вирівнювання компонентів
зроблено дуже зручно. Та й сам по собі дизайнер красивий. Є API для
вбудовування в програму. Підтримується передача параметрів. Поточна версія
містить багато помилок, тому частина заявлених функцій перевірити не вдалося.
Крім того, є серйозні проблеми зі створенням російськомовних звітів.
Зберігати шаблони російськомовних звітів можна тільки з використанням UTF-8.
Це саме по собі нормально. Тільки для збереження звіту в різних форматах
хлопці використовуються конструкції типу: p>
if (mode == 1) p>
dos.writeBytes (s);!! p>
else p>
dos.writeUTF (s); p>
Так
що зберігати шаблон звіту в UTF-8 і друкувати його на принтер ще можна. Але ось
записати його у форматі PDF або HTML з російськими літерами не вийде. Версія
4.02 є релізом, але от тільки помилок в ній стільки, що вистачить на пару
альфа-версій. Намалювати складний звіт в цьому продукті запросто, а от змусити
його працювати виявилося непросто.
p>
Rreport 1.1 p>
Можливості:
p>
Попередній
перегляд з масштабуванням p>
Використовується
дизайнер MS Access для побудови звітів та створення вихідного коду на Java p>
Режим
експорту в HTML p>
Підтримка
JDK 1.1 і 1.2 p>
Частина
вихідних кодів доступна після реєстрації p>
Ціни p>
Версія p>
Ціна p>
RChart Binary version (Includes only source
code of the applet) p>
$ 10 p>
Rchart with source code. (Includes source
code of all classes) p>
$ 20 p>
Rreport. Binary version p>
$ 30 p>
Rreport with source code. (Includes source
code of all classes) p>
$ 40 p>
URL:
http://rreport.port5.com/http://rreport.8m.com p>
Примітка:
Незважаючи на привабливі ціни, в існуючому вигляді продукт не підходить для
професійних додатків. Використання MS Access в якості дизайнера
звітів є зручним з точки зору простоти створення форм. Можна
розглянути можливість придбання вихідних кодів для їх подальшої
переробки.
p>
JClass Page Layout 4.5 p>
JClass
PageLayout є набором компонент реалізують функції перегляду звітів і
друку. Продукт надає функції API для додавання тексту, зображень та
таблиць до документів. p>
Можливості:
p>
Шаблони
сторінок p>
Книжкову
і альбомну орієнтація p>
Зумовлені
стилі таблиці p>
Інтеграція
з електронними таблицями p>
Вбудовану
підтримку діаграм p>
Заголовки
і підвали для сторінок p>
Автоматичну
нумерацію сторінок p>
Підтримка
розбиття статті на стовпці p>
Вирівнювання
тексту, відступи і табуляції p>
Виділення
кольором для сторінок, розділів і тексту p>
Малювання
ліній і бібліотека форм p>
Імпорт
зображень з GIF, JPG і EPS p>
Попередній
перегляд p>
Друк
на будь-який системний принтер (JDK 1.2 або вище) p>
Висновок
в PostScript, PDF, HTML, або HP PCL 5 p>
Ціни p>
Версія p>
Ціна p>
PageLayout Bytecode (Includes 1 year GSS) 4.5 p>
$ 875 p>
Gold Support with Subscription (purchased
separately) * (Includes source code of all classes) p>
$ 325 p>
URL:
http://www.klgroup.com p>
Примітка:
p>
Хоча
продукт і підтримує зовнішнє опис форм сторінок, він не має дизайнера для
виконання цієї роботи. Мається на увазі, що форми створюються в XML редакторі.
Опис форм у такий спосіб не є простою справою. Крім XML c описом
звіту ще треба і DTD докласти.
p>
JReport Professional 2.2 p>
Можливості:
p>
Підтримується
JDK 1.1, 1.2 і Microsoft Java VM p>
Побудова
зведених звітів з діаграмами, багатотабличних, підпорядкованих звітів, підтримка
функцій виводу на принтер, HTML, PDF, CSV, e-mail, або в текст p>
що визначаються
користувачем шаблони, формули і функції виходу p>
Доступ
до JDBC або призначеному для користувача джерела даних p>
Catalog
Browser - компонент використовується для побудови звіту, що включає джерела
даних, запити, формули, параметри і різні дані, і графічні об'єкти p>
Report
Inspector - властивості та значення для всіх об'єктів у звіті відображаються в
таблиці властивостей і можу бути інтерактивно змінені і відображені p>
Ціни p>
Версія p>
Ціна p>
JReport Professional Report designer with 100
local Runtime p>
$ 995 p>
URL: http://www.jinfonet.com/_vti_bin/shtml.exe/JReportRegister.htm
p>
Примітка:
p>
Виходячи
з опису, JReport Professional заслуговує серйозного розгляду. Однак
не вдалося отримати демонстраційну версію даного продукту. Якщо хто має
хоча б евалюшен - буду вдячний якщо поділитеся.
p>
Elexir Report 1.2 p>
Elixir
Report - крос платформенне Java рішення для побудови звітів з
використанням різних джерел даних, включаючи XML. Elixir Report може
використовуватися для розробки звітів і вбудовуватися в Java-додатки. p>
Можливості:
p>
Різні
типи джерел даних - Java Objects і JDBC p>
Підтримка
аплетов p>
Динамічна
завантаження зображень p>
Середа
управління проектами з контролем версій p>
майстри
побудови звітів і підключення до джерел даних p>
Безкоштовний
runtime p>
Ціни p>
Версія p>
Ціна p>
Single Developer Licence p>
$ 149 p>
5-Developer Licence Pack p>
$ 675 p>
15-Developer Licence Pack p>
$ 1900 p>
25-Developer Licence Pack p>
$ 2980 p>
* Gold Support and Subscription per Developer
(renewable annually) p>
$ 500 p>
URL:
http://www.elixirtech.com/ElixirReport/ p>
Примітка:
p>
Elixir
Report - в цілому справив хороше враження. Доданий до нього дизайнер
звітів володіє необхідною функціональністю, хоча й поступається ERW 4.0.2.
Підтримується передача параметрів для побудови звіту. Є майстри
підключення до джерел даних і побудовники шаблонів звітів. Немає проблем з
побудовою російськомовних звітів. Самі шаблони звітів зберігаються в XML. Крім
того є вбудовані засоби управління проектом. Повна русифікація runtime
не можлива. У цілому не дуже гарний, але працюючий продукт.
p>
Root River Delta p>
Root
River Delta - набір API для вбудовування функцій перегляду і друку звітів у
додатки. Підтримує різні джерела даних, включаючи JDBC, EJB і Java
Objects. Дизайнера звітів поки не має. p>
Можливості:
p>
Зовнішній
вид звіту повністю не залежить від формату його виведення. Підтримується висновок
звітів в Bitmap, Java-сумісний принтер, PDF, HTML, PCL5, ASCII або CSV
текст p>
Є
засобу перегляду звітів для вбудовування в додатки і аплети p>
Реалізація
на AWT 1.1 забезпечує максимальну переносимість p>
Підтримуються
різні шрифти та стилі, зображення p>
API
побудовано з метою спростити і прискорити побудову великих за обсягом звітів.
Передбачена підвантаження даних у звіт в процесі перегляду p>
Ціни p>
Версія p>
Ціна p>
Рer developer (runtime components of RR Delta
for internal use only) p>
$ 250 p>
URL: http://www.rrsys.com/ p>
Примітка:
p>
Виробляє
гарне враження. Однак відсутність дизайнера звітів, не дуже зручна і
детальна документація, а так само деяка складність API вимагають досить
високої кваліфікації для його використання. Root River Delta поступається
аналогічним продуктам, таким як Style Report і JClass Page Layout.
p>
Generic
Report Writer p>
підтримки PostgreSQL, MySQL, і Access. Також сумісний з
будь-якими базами даних мають Type 4 JDBC драйвер. Реалізовано на Java 1.2.
Розповсюджується в рамках ліцензії GPL (доступні вихідні коди). Є
примітивний дизайнер звітів. Звіти можна отримати тільки в текстовому форматі.
Шрифти і зображення не підтримуються. p>
Ціни:
Free p>
URL:
http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html
p>
Примітка:
p>
...
Ну що месьє хотів за один @? Але в деяких випадках може й підійти. Автор
обіцяє розвивати цей продукт.
p>
Java Report Engine - i-net Crystal-Clear p>
i-net
Crystal-ClearT це виконуюча середовище для звітів створених в Seagate Crystal
Reports Designer. Призначений для додавання функцій перегляду і друку
звітів в додатки і аплети. i-net Crystal-ClearT може використовуватися як
платформні-незалежне розширення для рішень на базі Crystal Report для
вбудовування в додатку. Crystal-ClearT підтримує формати Seagate Crystal
Reports 6.0, 7.0 і 8.0 p>
Ціни p>
Версія p>
Ціна p>
20 User License p>
$ 200 p>
Enterprise License p>
$ 500 p>
Web-License p>
$ 700 p>
Application License p>
$ 1990 p>
URL:
http://www.inetsoftware.de/English/Produkte/CrystalClear/Default.htm p>
URL:
http://www.seagatesoftware.com/products/crystalreports/default.asp p>
Примітка:
p>
Основне
гідність даного продукту - підтримка Seagate Crystal Reports, який
фактично може вважатися промисловим стандартом для корпоративних систем.
Хоча заявлено, що процесор i-net Crystal-ClearT працює швидше
оригінальному Seagate Crystal Reports, це не помітно. Є гарний
runtime, яким ще й досить гнучко управляти можна. Едінтсвеное, що
відмічено поганого, свіхівается на складних SQL виразах. Є про нього і відлуння
на news.inetsoftware.de/crystalclear. Коротше, є сенс звернути на нього
увагу.
p>
Style Report Data Source Edition Lite p>
Style
Report DataSource Edition - є розширенням Style Report Lite 3.0 до якого
додані повнофункціональні засоби для роботи з різними джерелами
даних. Style Report Lite - являє собою набір API з допомогу якого
можна додавати функції перегляду і друку в свої додатки. Засоби
побудови запитів і підключення до джерел даних в Style Report DataSource
Edition маються на дизайнера звітів. Вони також доступні і через виклики API.
Підтримуються наступні типи джерел даних: p>
XML p>
Реляційні БД (JDBC) p>
CORBA p>
Enterprise JavaBeans p>
Текст
p>
Можливості:
p>
SQL-подібний
синтаксис запитів p>
секцій
щодо розміщення та фільтрації даних p>
Підтримуються
підзапит p>
Є
API інтерфейс до управління запитами p>
Підтримується
передача параметрів в запити p>
Друк
з аплетов і в PDF p>
Ціни p>
Версія p>
Ціна p>
Style Report/Lite p>
Free p>
Style Report/Pro p>
$ 995 p>
Style Report/Source p>
$ 3995 p>
Style Report/Enterprise (Include one
development server runtime license) p>
$ 2980 p>
Runtime p>
Безкоштовний для продуктів, не
які є засобами розробки. p>
URL: http://www.inetsoftcorp.com/ p>
Примітка:
p>
До
жаль, довелося мати справу тільки з бета-версією даного продукту, яку
не вдалося змусити працювати. Однак бета-версія продукту Style Report Lite
3.0 заслуговує самої пильної уваги. З усіх протестованих засобів
побудови звітів, її більшою мірою вдалося русифікувати. Управління
звітом на рівні API дозволяє домогтися велике гнучкості і комбінувати самі
різноманітні дані програми. Підтримуються шрифти, зображення, багатий
набір стилів таблиць. Однак розплатою за це є необхідність
програмування звітів. Дизайнер звітів більше орієнтований на побудову
розмітки сторінки, ніж на описи секцій звіту, що ускладнює побудову
звітів з угрупуваннями. Така обробка виноситься на рівень програми, і
елементи звіту передбачається створювати з програми без допомоги дизайнера.
Версії Style Report DataSource Edition є набагато більш зручним засобом
для побудови звітів з баз даних, однак побачити її функціональність
не вдалося. У цілому цей продукт є серйозним претендентом на вбудовування
в додатки. Хоча вимагає досить високої кваліфікації для створення звіту.
До недоліків, можна також віднести неможливість запустити виконання звіту під
фреймі програми. Якщо потрібно скласти кілька вбудованих у додаток
звітів StyleReport прекрасно для цього підійде.
p>
Засоби для побудови звітів, не включені до
тестування p>
EspressChart. p>
EspressChartTM is a set of tools that
enables you to easily include dynamic charts in your Java applications and on
your Web pages. You can display the chart as a Java applet or PNG/GIF/JPEG
image in your browser. (Note: EspressChart can be used in a servlet to generate
PNG/GIF/JPEG images on the server dynamically.) It is written in 100% pure Java
so it is completely platform independent. EspressChart supports JDBC/ODBC for
retrieving and plotting data from any database. p>
URL:
http://www.quadbase.com/espresschart/index.html p>
NetCharts. p>
NetCharts is a suite of Java applets
that allows HTML authors, web developers, and Java programmers to quickly and
easily create on-line charts from virtually any data source, with minimal
coding. NetCharts supports any Java 1.0.x or 1.1.x enabled platform, including
PCs, UNIX and network computers. All applets can be viewed through any Java
compatible Web browser and support the use of the JDBC interface to retrieve
parameter definitions or data values from one or more database servers or data
sources, including Oracle, Sybase, Informix, DB2, Microsoft SQL Server, dBase,
Access and Excel. p>
URL:
http://www.cartworks.com p>
Java:
Конфігурація програм. P>
Зміст: p>
Навіщо
потрібно конфігурування? p>
Що
саме варто налаштовувати. p>
Способи
зберігання настройок. p>
Ini-файли.
p>
Файли
Properties. p>
XML-файли.
p>
сериализация.
p>
Бази
даних. p>
Скрипти.
p>
Приклад
програми з конфігурацією в XML. p>
Навіщо потрібно конфігурування? b>
p>
Професійним
програмістам це питання здасться дивним. У початківців ж часто спостерігається
явне нерозуміння важливості цієї можливості. При цьому виходить програма,
схожа на кам'яну брилу з висіченим на ній написами - якщо захочеться
змінити напис, то доведеться робити новий камінь. p>
Є
й інша крайність - коли практично всі виноситься в налаштування. Такі
програми нагадують розлиту рідину, а щоб змусити її працювати треба
прочитати талмуд опису та налаштувати кілька сотень параметрів, до того ж
часто взаємопов'язаних протиприродним чином. p>
Як
завжди треба знайти золоту середину - з одного боку треба постаратися
задовольнити різні примхи користувачів, з іншого боку потрібно зробити
так, щоб більшості користувачів нічого налаштовувати не довелося. p>
Що саме варто налаштовувати. b>
p>
Ось
типові приклади даних, які часто варто винести в налаштування: p>
Всілякі
каталоги. Наприклад - шляхи до файлів даних, каталоги імпорту/експорту. p>
Мережеві
налаштування. Імена серверів, IP-адреси, порти, імена та паролі для автоматичного
доступу. p>
Настройки
баз даних. Імена JDBC-драйверів, URL бази даних, SQL-запити, залежні від
використовуваної БД. p>
Настройки
зовнішнього вигляду. Установки Swing-івського Look & Feel-а, що використовуються шрифти,
розміри, кольори, настройки гарячих клавіш. p>
Інше ...
Будь-які інші речі, які можуть змінюватись від користувача до користувача. p>
Наприклад,
досить часто зустрічається ситуація - настройка з'єднання з БД. Початківці
програмісти часто пишуть щось подібне: p>
Class.forName ( "sun.jdbc.odbc.JdbcOdbcDriver "); p>
Connection con =
DriverManager.getConnection ( "jdbc: odbc: MyDatabase", user, password); p>
Таким
чином програма прив'язується до конкретного JDBC драйверу. Використовувати
інший драйвер, наприклад замінити міст на RMI-проксі або, у разі Oracle, OCI
на Thin без перекомпіляції вже не можна. p>
Способи зберігання налаштувань. b>
p>
В
об'єктному програмуванні все представляється у вигляді об'єктів. Установки краще
за все при цьому розглядати як властивості певних об'єктів, які
зберігаються у файлах конфігурацій. Те, яким чином ці налаштування зчитуються і
записуються тісно взаємопов'язане з форматом файлів і вибраною стратегією
адміністрування. Розглянемо ідеальний варіант: p>
Нас?? влаштовує
об'єкт не повинен містити знань про формат файлів і способі читання/запису. Це
дозволило б, у разі необхідності, замінити один спосіб іншим. p>
Більшість
установок повинні виконуватися за допомогою програми (підпункт меню або окрема
програма установки). Це сильно полегшує життя людини, яка займається
адмініструванням. У більшості "юніксоідов" це може викликати
нерозуміння :-), але редагуванням текстових файлів в сучасному світі у
багатьох випадках не обійтися. p>
Повинно
бути встановлено розумне умовчання для відсутніх параметрів. Іншими
словами - необхідно, щоб більшості користувачів для запуску програми
потрібно було б зробити мінімум налаштувань. Як правило це залишає сприятливе
перші враження про програму, а часто саме воно - найважливіше. p>
До
жаль цей ідеальний варіант досить важко зробити на практиці. Перше
вимога передбачає розробку універсального механізму збереження
об'єктів. Такі системи вже є готові, але часто вони не підходять з тих чи
іншими параметрами. Розробити ж самому таку систему - далеко не кожному під
силу. p>
Друге
вимога має на увазі, що для кожного об'єкта пишеться своя панель (або
діалог) для редагування настройок. У випадку великої кількості об'єктів
варто спробувати використовувати універсальні механізми. Один з варіантів --
використання стандарту JavaBeans. Цей стандарт розроблявся для візуальних
систем програмування, але, через схожість вирішуваних завдань, також добре
підходить для універсального конфігурування. Але це теж не найпростіша
завдання, тому часто розумно передбачити можливість альтернативного
варіанти конфігурування для пожежних випадків - наприклад, за допомогою звичайних
текстових редакторів у випадку використання текстових форматів файлів. p>
Розумне
ж умовчання для параметрів часто просто неможливо уявити. Наприклад, що
поставити як ім'я SMTP-сервера? У разі Unix-систем можна спробувати
поставити localhost, але для Windows-світу це рідко кому підійде. p>
Розглянемо
найпоширеніші варіанти:
p>
Ini-файли. p>
Ini-файли
- Це був найпоширеніший варіант в епоху Windows 3.x. Зараз в віндового
програмах він став витіснятися зберіганням настройок в реєстрі. Тим не менше ini --
це один з найпростіших варіантів зберігання настройок. На жаль досить часто
ця простота змушує вдаватися до різноманітних хитрощів. Приклад типового ini-файла: p>
[Communication] p>
InputDir = INPUT p>
OutputDir = OUTPUT p>
ArchDir = ARHIV p>
TransferPath = a: cour p>
[Warning] p>
NoReceived = No p>
[Addons] p>
Numb = 3 p>
MenuName1 = ~ N ~ orton p>
ProgName1 = mousesav c: command.com
/ c nc p>
MenuName2 = Win - ~ Б ~ локнот p>
ProgName2 = notepad p>
MenuName3
= Імпорт з формату АБ "Інкомбанк" p>
ProgName3
= Incom.bat p>
В
Java немає стандартного класу для читання ini-файлів, але це не проблема. Оскільки
формат дуже простий, його легко зробити самому: p>
import
java.io. *; p>
import java.util .*; p>
public class INIFile p>
( p>
Properties iniProperty = new Properties (); p>
public INIFile (File f) (this (f.getPath ());
) p>
public INIFile (String fname) throws
IOException (loadFile (fname);) p>
private void loadFile (String fname) throws
IOException p>
( p>
BufferedReader br = new BufferedReader (new InputStreamReader (new
FileInputStream (fname ))); p>
try p>
( p>
String section = ""; p>
String line; p>
while ((line = br.readLine ())!= null) p>
( p>
if (line.startsWith (";"))
continue; p>
if (line.startsWith ("[")) p>
( p>
section =
line.substring (1, line.lastIndexOf ("]")). trim (); p>
continue; p>
) p>
addProperty (section, line); p>
) p>
) p>
finally (br.close ();) p>
) p>
private void addProperty (String section, String
line) p>
( p>
int equalIndex = line.indexOf ("="); p>
if (equalIndex> 0) p>
( p>
String name = section +'.'+ line.substring (0, equalIndex). Trim (); p>
String value = line.substring (equalIndex +1). Trim (); p>
iniProperty.put (name, value); p>
) p>
) p>
public String getProperty (String
section, String var, String def) p>
( p>
return iniProperty.getProperty (section +'.'+ var, def); p>
) p>
public int getProperty (String section, String
var, int def) p>
( p>
String sval = getProperty (section, var, Integer.toString (def )); p>
p>
return Integer.decode (sval). intValue (); p>
) p>
public boolean getProperty (String
section, String var, boolean def) p>
( p>
String sval = getProperty (section, var, def?
"True": "False "); p>
return sval.equalsIgnoreCase ( "Yes") | | sval.equalsIgnoreCase ( "True "); p>
) p>
) p>
Файли Properties.
p>
Цей
формат поширений в Unix-світі. Він ще простіше ini-файлів, тому що в ньому
відсутнє поняття секцій - все складається з ключів і значень. Приклад типового файлу: p>
# Database configuration p>
Database.Driver = sun.jdbc.odbc.JdbcOdbcDriver p>
Database.DataURL = jdbc: odbc: MyDatabase p>
Database.Prop.user = user p>
Database.Prop.password = password p>
В
Java є готовий клас для читання/запису таких файлів (java.util.Properties),
але з ним є деякі проблеми. У першому для читання неможливо задати
кодування файла, а це означає проблеми з російськими літерами. По друге
стандартна функція запису зберігає дані в тому порядку, хеш-значень
ключів, що означає - як їй більше сподобається. Але це теж легко здійсненне --
достатньо написати свою читалку/писалка. p>
XML-файли. p>
Цей
формат підходить для багатьох цілей, в тому числі і для зберігання налаштувань.
XML-формат орієнтований на деревоподібні структури, що досить природнім
чином відображається на об'єкти. Приклад типового файлу: p>
xml version = "1.0"
encoding = "Windows-1251 "?> p>
p>
driver = "sun.jdbc.odbc.JdbcOdbcDriver" p>
dataURL = "jdbc: odbc: MyDatabase"> p>
user prop> p>
password prop> p>
database> p>
Для
читання і запису таких файлів призначені спеціальні бібліотеки - так
звані XML-парсер. Таких парсерів вже зроблено досить багато, так що
писати його самому немає великого сенсу - достатньо лише підібрати відповідний.
Для парсерів було розроблено два стандартних програмних інтерфейсу --
подієвий (SAX) і ієрархічний (DOM). Є також і парсер зі своїм
інтерфейсом. Розмір jar-а з парсерів може варіюватися від кількох кілобайт
до мегабайта - залежно від підтримуваних інтерфейсів і можливостей. p>
Для
XML також написано декілька бібліотек для універсального збереження
(сериализации) об'єктів у файлах XML. Такі бібліотеки дозволяють відокремити
алгоритм збереження від самого об'єкта, а це, як уже згадувалося, має багато
плюсів.
p>
сериализация. p>
Під
терміном "сериализация" розуміють запис вмісту об'єкта в потік
двійкових даних. Звичайно мається на увазі універсальний алгоритм, реалізований
класами java.io.ObjectOutputStream і java.io.ObjectInputStream. Користуватися
ними просто настільки, наскільки це взагалі можливо - зазвичай достатньо лише
відзначити в класі підтримку за допомогою інтерфейсу Serializable і відзначити
ключовим словом transient ті поля об'єкта, які зберігати не потрібно. Собсно і
все. :-) Приклад: p>
public class SerialObject implements
java.io.Serializable p>
( p>
private String name; p>
private transient int state; p>
public SerialObject () () p>
public SerialObject (String n) (name = n;) p>
public String getName () (return name;) p>
public void setState (int s) (state = s;) p>
) p>
Запис об'єктів: p>
SerialObject o = ...; p>
OutputStream os = ...; p>
ObjectOutputStream oos = new
ObjectOutputStream (os); p>
oos.writeObject (o); p>
Читання
об'єктів: p>
InputStream is = ...; p>
ObjectInputStream ois = new ObjectInputStream (is); p>
SerialObject o =
(SerialObject) ois.readObject (); p>
Використання
сериализации - це один з найпростіших варіантів по реалізації, але й у нього
є свої недоліки. Отримані файли є двійковими, а значить у текстовому
редакторі їх вже не підправити - доведеться робити редагування параметрів з
програми. Крім того, необхідно стежити за зміною збережених об'єктів,
щоб не порушити сумісність при зміні і розвитку програми. p>
Бази
даних. p>
В
базах даних можна зберігати будь-які дані, конфігурація програми - не
виняток. Це має сенс у кількох випадках: p>
Настройки
пов'язані вельми складним чином і деревоподібні структури типу XML підходять погано.
p>
Доступ
до налаштувань повинен бути тільки у авторизованих користувачів. p>
Доступ
до цих даних повинен бути і з інших програм, наприклад з генератора звітів
типу Crystal Reports. p>
БД
можуть застосовуватися об'єктні або реляційні. Інші типи зараз широкого
розповсюдження не мають. Використовувати хорошу об'єктну БД часто так само
просто, як і сериализации. Для реляційних баз можна застосувати об'єктну
надбудову, яка також дозволяє сильно спростити життя. Ну а можна робити
звичайні SELECT-и.
p>
Скрипти. p>
Використання
скриптів - це один із самих екстремальних способів конфігурування. Вони
дозволяють досягнути максимальної гнучкості програми за рахунок винесення логіки
назовні. У використанні скриптів теж треба знати міру - зрештою замовник
платить Вам за програму, що вирішує завдання, а не за ще один інтерпретатор чи
компілятор за який йому буде потрібно посадити ще одного програміста. А то
виходить, як у тому анекдоті - яку програму не почнеш писати, всі
компілятор виходить. p>
Але
часто без скриптів дійсно важко. Типові приклади - алгоритми
імпорту/експорту, алгоритми перевірок даних. Ви можете підготувати стандартний
набір, а далі налаштовувати скриптами під конкретні вимоги замовника. p>
Для
програм на Java в якості скрипт-мови добре використовувати мову Python в його
Java-інкарнації під назвою JPython. Там легко організувати двосторонній зв'язок
між програмою і скриптом. Якщо не буде вистачати швидкості інтерпретації, то
код на Python-і можна скомпілювати в байт-код - вийде звичайний Java-клас.
Про JPython можна почитати на сайті www.jpython.org або в новій книжці Брюса
Еккеля Thinking In Patterns with Java (доступна на www.bruceeckel.com). p>
Приклад програми з
конфігурацією в XML. b>
p>
В
Як приклад можете побачити простеньку програми, що використовує XML-файл
як конфігураційного. Зберігати параметри можна редагувати як з
програми, тому за допомогою текстового редактора. p>
XMLConfig.java
p>
Приклад
вмісту конфігураційного файлу: p>
xml version = "1.0"
encoding = "Cp1251 "?> p>
Просто рядок p>
Друга
рядок program> p>
В
як XML-парсера використовується Sun-івської парсер в режимі DOM. На такому
простому прикладі не видно особливих переваг формату XML над тими ж файлами
properties. Вони стають помітні тільки в досить складних програмах, де
стає необхідно зберігати списки однотипних параметрів або ж вміст
об'єктів з рівнем вкладеності два або більше. p>
Pascal: Робота з файлами p>
У минулому випуску ми з вами почали писати програму,
яка і повинна була стати основоположною в наших подальших діях.
Програма називалася "Записна книжка", маніпулювала з типом record
і ще містила маленьку помилочка, яку, до речі, багато хто помітив. p>
Зверніть увагу на цей код: p>
...... p>
C: = ReadKey; p>
case C of p>
'1 '.. '9': begin p>
Val (C, I, Code); p>
List_Item (I); p>
end; p>
'a': New_Item; p>
# 27: Quit: = true; p>
end; p>
...... p>
У цьому вся собака зарита. Справа в тому, що в умові
згадується про роботу з 10-ма записами, а цей алгоритм дозволяє використовувати
всього дев'ять, тому що взагалі не вміє читати двозначні числа. Як вирішити це
питання - Ваша задача! Програмування взагалі без завдань, які потрібно вирішувати,
не обходиться ... p>
Ну а ми інтенсивно рухаємося далі. Сьогодні - як і було
обіцяно, файли. Поки тільки теорія, яку вам потрібно засвоїти (її досить
багато), практика буде в наступному випуску. p>
Робота з файлами p>
у Паскалі робота з файлами здійснюється через спеціальні
типи, досі нам не відомі. Це файлові типи, які визначають тип файлу,
тобто фактично вказують його вміст. За допомогою цієї змінної, якій
визначено необхідний тип, і здійснюється вся робота з файлами - відкриття,
запис, читання, закриття і т.п. p>
час роботи з файлами існує певний порядок
дій, якого необхідно дотримуватися. Ось усі ці дії: p>
Створення (опис) файлової змінної; p>
Зв'язування цієї змінної з конкретним файлом на диску або
з пристроєм введення-виведення (екран, клавіатура, принтер і т.п.); p>
Відкриття файлу для запису або читання; p>
Дії з файлом: читання або запис; p>
Закриття файлу. p>
Перше, на що хочу звернути увагу, це можливість
зв'язати файлову змінну не тільки з фізичним файлом на носії
інформації, але і з пристроєм. У якості такого використовуються звичайні
псевдоніми пристроїв DOS. Ось основні два: p>
CON - консоль (екран-клавіатура), тобто за записом в цей
пристрій ми будемо отримувати інформацію на екран, при читанні інформації з
цього пристрою, будемо читати дані з клавіатури. p>
PRN - принтер. При записі в цей пристрій ви отримаєте
інформацію на принтер. p>
Далі хочу звернути увагу на останній етап - закриття
файлу. В принципі, не обов'язкова умова для файлів, з яких ми читаємо
дані. Якщо не закриємо - помилки це не викличе, наслідків теж. Однак
обов'язково закривати файл, якщо ми здійснювали в нього запис. Справа в тому, що
якщо ми пишемо дані у файл на диску і забуваємо його закрити - інформація не
зберегтися. Вона (інформація) поміщається в тимчасовий буфер, який запишеться
на диск тільки при закритті файлу. p>
Типи файлових змінних p>
Перед тим, як починати роботу з файлами, давайте
подивимося, які існують змінні для роботи з ними. У Turbo Pascal
є три типи таких змінних, які визначають тип файлу. Ось ці типи: p>
Text - текстовий файл. З змінної такого типу ми зможемо
читати рядки й символи. p>
File of _любой_тіп_ - так звані
"типізовані" файли, тобто файли, що мають тип. Цей тип
визначає, якого роду інформація міститься у файлі і задається в
параметре_любой_тіп_. Наприклад, якщо ми напишемо так: p>
F: File of Integer; p>
Те Паскаль буде вважати, що файл F містить числа типу
Integer; Відповідно, читати з такого файлу ми зможемо тільки змінні типу
Integer, рівно як і писати. Напишемо так: p>
type p>
A = record p>
I, J: Integer; p>
S: String [20]; p>
end; p>
var p>
F: File of A; p>
Те отримаємо дуже цікаву картину, коли файл містить в
як елементи запису. Ми зможемо їх читати, писати і проводити з ними
дії. Саме цим ми і займемося в процесі модифікації нашої програми
"Записна книжка". p>
File - нетипізований файл. Коли ми вказуємо як
типу файлу просто File, тобто без типу: p>
F: File; p>
Те отримуємо "нетипізований" файл, читання і
запис у який відрізняється від роботи з файлами інших типів. Ці дії
виробляються шляхом зазначення кількості байт, які потрібно прочитати, а також
зазначенням області пам'яті, в яку потрібно прочитати ці дані. Це тема
майбутніх випусків. p>
Отже, розібралися з типами файлів. Тепер давайте по
порядку розбирати дії, які застосовуються для роботи з файлами. Я говорив про них
вище. p>
Зв'язування змінної з файлом p>
Самий універсальний крок. Виконується однієї і тієї ж
процедурою для всіх типів файлів, а саме процедурою Assign: p>
Assign (_переменная_файлового_тіпа_, 'шлях до файлу'); p>
Як бачите, в якості параметрів задаються мінлива
лібого файлового типу та рядок - шлях до файлу, який, за правилами DOS, не
може бути довше 79 символів. Ось приклад використання assign: p>
var p>
T: Text; p>
F1: File of Byte; p>
F2: File; p>
begin p>
Assign (T, '1. txt '); p>
Assign (F1,
'C: ProgrammTp2.txt'); p>
Assign (F2,
'F: usr_inapacheconfhttpd ~ 1.con'); p>
.......... p>
Як бачите, це дуже просто і сама процедура Assign
проблем не викликає. Давайте тепер розглянемо наступний етап. p>
Відкриття файлу p>
Відкриття файлу - це вже більш ускладнений процес, ніж
зв'язування з ним змінної. Тут враховується, навіщо відкривається файл - для
запису або читання, а також у залежності від типу файлу процедури виконують
різні дії. p>
Проте цей процес не складний і полягає в
використання однієї з трьох наявних процедур: p>
Reset (_любая_файловая_переменная_); p>
Откриват файл на читання. Як параметр - файлова
мінлива будь-якого з перерахованих вище типів. Це може бути текстовий,
типізований або не типізований файл. У випадку з текстовим файлом, він
відкривається тільки на читання. У випадку з типізований і нетипізований
файлом - він відкривається на читання і запис. p>
Append (T: Text); p>
Ця процедура відкриває текстовий файл (тільки текстовий!)
на запис. Вище я сказав, що Reset при завданні параметра типу Text не дозволить
писати в нього дані, відкривши файл лише для читання. Тобто якщо ви використовуєте
текстовий файл і хочете робити в нього запис, нужнo використовувати Append.
Якщо читання - Reset. В інших випадках справа обходитися однією процедурою
Reset. p>
Також зверніть увагу, що якщо ви до цього вже відкрили
файл на читання, вам не потрібно закривати його й відкривати знову на запис. У цьому
випадку файл закривається сам і відкривається наново. При запису даних у файл при
відкритті його за допомогою пов?? й процедури вони записуються в кінець файлу. p>
ReWrite (F) - створює новий файл або перезаписує
існуючий. Будьте обережні, якщо не хочете випадково видалити потрібний файл.
Нагадаю, файл, відкритий за допомогою цього процесу буде повністю перезаписаний. p>
У використанні процедур, думаю, проблем не буде. Однак
виникає інше питання - що, якщо файлу, який відкривається, ні? Якщо він не
існує на диску, то як ми зможемо з нього читати інформацію? Програма
виб'є помилку в такій ситуації. Це реальна проблема, яка, до речі, дуже
просто вирішується. p>
Спосіб перевірки полягає в двох етапах: використанні
ключів компілятора і функції IOResult, яка повертає значення від тільки
що виконаної операції вводу-виводу. З функцією розберемося швидко, а от з
такою штукою як ключі компілятора ми ще не стикалися, тому зупинимося
докладніше. p>
Ключі компілятора - це звичайні перемикачі, які
контролюють хід виконання програми виключаючи або включаючи реакцію на
будь-які умови. У нашому випадку нас цікавить умова, коли фізично
відсутній потрібний нам файл, або не вдалося відкрити його з інших причин.
Ключів у Паскаля досить багато, ми поки що вивчимо один, необхідний нам на даний
момент. p>
Оформляються ключі такий спосіб: у дужках коментарів
"()" Першим символом після відкриває дужки "(" ставиться
знак долара "$", після чого вказується ім'я ключа і його значення.
Нас цікавить ключ, який вимикає висновок помилок вводу-виводу, називається він
"I". Виглядає все це в такий спосіб: p>
($ I +) - включення виводу помилок p>
($ I-) - вимкнути виведення помилок p>
По суті справи відсутній файл - це помилка, яка
повертається функцією IOResult. Якщо ж ця функція повертає 0, то файл
успішно відкрито, без помилок. От і вимальовується послідовність дій,
необхідних для перевірки на наявність файлу: p>
пов'язуємо змінну з файлом; p>
Вимикаємо висновок помилок на екран - ($ I-) p>
Відкриваємо файл необхідної нам процедурою; p>
Включаємо висновок помилок ($ I +) - нехай буде для подальшого
відстеження таких; p>
Перевіряємо, якщо IOResult повертає нуль, то все було шляхом
і файл відкритий. Інакше виводимо помилку. p>
Ось приклад такої програми: p>
var p>
T: Text; p>
S: String; p>
begin p>
Write ( 'Enter filename:'); p>
Readln (S); p>
Assign (T, S); p>
($ I-) p>
Reset (T); (відкриваємо файл для читання) p>
($ I +) p>
if IOResult <> 0 then (якщо не нуль,
то була помилка) p>
begin p>
Write ( 'Error
when open file '); p>
Halt; p>
end; p>
(інакше все в порядку, продовжуємо) p>
.......... p>
end. p>
Закриття файлу p>
Вище я говорив про те, навіщо потрібно закривати файл і коли
треба це робити. Закриття файлу проводитися за допомогою процедури Close (F), де
F - це змінна файлового типу. Ця процедура один для всіх типів файлів. p>
Запис і читання файлів. Частина I p>
Сьогодні я хочу розповісти про запис і читанні текст