Главная > Программирование > Web-программирование > |
FAQ по языку Java |
Секция 4 из 7 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
- 4
- 5
- 6
- 7
К тому же, ваши Windows95 приложения могут совместно использовать СОМ-порты (с любыми модемами на портах) с помощью ПО "Dial-out IP" под Windows95. Смотрите здесь: http://www.tactical-sw.com/. Если порт подмонтирован к файловой системе, вы можете использовать его как файл, открывая для чтения и/или записи. Таким же путем можно выводить на печать текст, копируя его в устройство "prn" или "lpt1" на РС-совместимых системах (обязательно завершив текст символом конца файла), или в "/dev/что-нибудь" в Unix. Ниже приведен пример: // класс, открывающий принтер как файл // и записывающий в него строку "Hello, world" import java.io.*; public class lpt { public static void main (String[] argv) { try { FileOutputStream os = new FileOutputStream("LPT1"); //создаем "дружественный" PrintStream PrintStream ps = new PrintStream(os); //выводим текст ps.println("Hello world!"); //признак конца файла -- это важно //Без него текст просто попадет в буфер принтера // пока что-нибудь еще не будет выводиться на печать. ps.print("\f"); //сбрасываем буфер и закрываем поток ps.close(); } catch (Exception e) { System.out.println("Exception occurred: " + e); } } } Если необходимо изменить характеристики порта (напр., скорость или четность), а не просто писать или считывать данные, то, к сожалению, Java на данный момент не имеет переносимых решений для этой проблемы. Вам придется воспользоваться одной из библиотек, указанных выше, или же обратиться к системно-зависимому коду или утилите. *(Часть 7) Как я могу сделать быстрее ввод/вывод? Моя программа копирования файлов работает медленно. [*] Для этой цели надо использовать BufferedInputStream. Недостатком Java явлется то, что буферизованный ввод/вывод не используется по умолчанию; можно было бы использовать некий флаг или альтернативный конструктор для его отключения. Пакет ввода/вывода - второй наиболее плохо реализованный пакет в Java после класса Data. *(Часть 7) Как я могу организовать форматированный ввод/вывод вещественных чисел? [*] Используйте класс java.text.NumberFormat. Также вы можете использовать http://www.newbie.net/sharky/lava/, или используйте пакет Cay Horstmann'а http://www.horstmann.com/corejava/Format.java Несмотря на то,что много различных утилит заявляют поддержку всех возможностей функции printf языка C, только вышеприведенные пакеты корректно поддерживают эквивалент %e в printf. *(Часть 7) Как я могу прочитать числа в научном (экспоненциальном) формате? [*] Нижеприведенная программа, написанная Steve Chapel, использует класс StreamTokenizer для того, чтобы прочитать данные из стандартного ввода и распознать вещественные числа двойной точности (double) в экспоненциальном формате (например, -1.23e-45). import java.io.*; public class ReadExponential { public static void main(String argv[]) { DataInputStream in = new DataInputStream(System.in); StreamTokenizer st = new StreamTokenizer(in); try { while (st.nextToken() != StreamTokenizer.TT_EOF) { switch (st.ttype) { case StreamTokenizer.TT_NUMBER: double num = st.nval; int exp = 0; st.ordinaryChars('\0', ' '); st.nextToken(); st.whitespaceChars('\0', ' '); if (st.ttype == StreamTokenizer.TT_WORD && Character.toUpperCase(st.sval.charAt(0)) == 'E') { try { exp = Integer.parseInt(st.sval.substring(1)); } catch (NumberFormatException e) { st.pushBack(); } } else if (st.ttype < 0 || st.ttype > ' ') st.pushBack(); System.out.println("Num " + num * Math.pow(10, exp)); break; case StreamTokenizer.TT_WORD: System.out.println("Word " + st.sval); break; default: System.out.println("Char '" + (char) st.ttype + "'"); break; } // end switch } // end while } catch (IOException e) { System.out.println("IOException: " + e); } } // end main } *(Часть 7) Я пытаюсь прочитать символ из текстового файла, используя метод readChar() класса DataInputStream. А когда я пытаюсь его напечатать, получаю символы '?'. [*] Помните, что в Java используются 16-битные символы Unicode, в то время как многие системы хранят символы как 8-битные в кодировке ASCII. Таким образом, чтобы прочитать отдельные символы из текстового файла, необходимо убедиться в правильной конвертации. Правильно это делается так - используйте InputStreamReader, который преобразовывает поток из 8-битного в 16-битный: FileInputStream fis = new FileInputStream("myfile.txt"); InputStreamReader isr = new InputStreamReader(fis); char c3 = (char) isr.read(); Другой, менее предпочтительный путь, состоит в том, чтобы прочитать байт и преобазовать его в символ: FileInputStream fis = new FileInputStream("myfile.txt"); DataInputStream dis = new DataInputStream(fis); char c1 = (char) dis.readByte(); *(Часть 7) Как удалить директорию в Java? [*] JDK 1.0 не поддерживает удаление директорий. JDK 1.1 поддерживает удаление директорий при помощи метода public boolean delete() класса java.io.File Убедитесь, что в директории, которую вы собираетесь удалить, нет ни одного открытого потока (stream). Выполните команду close() для всех потоков, даже если читаемый файл закончился (the underlying file is gone). *(Часть 7) Как я могу узнать, сколько свободно дискового пространства? [*] На данный момент не существует хорошего API (программного интерфейса) для инспектирования системы. В Java невозможно контролировать процессы или смотреть на ресурсы системы. Вы можете использовать Runtime.getRuntime().exec() для вызова "df" в юниксе или "dir" в Windows. С другой стороны, взгляните на JConfig по адресу: http://www.tolstoy.com/samizdat/jconfig.html JConfig - это межплатформенная библиотека, которая заполняет многие промежутки в Java API, и дает возможность работать с файлами, процессами, мониторами и т.д. в манере, напоминающей Windows или Mac. *(Часть 7) Как я могу получить список файлов в каталоге C:\ ? [*] Кажущийся очевидным подход - вызвать File.list("C:\") - не работает. Для этого есть две причины. Во-первых, \ (slash) является escape-символом в Java, то есть, если вам нужен этот символ, надо написать его дважды. Во-вторых, необходимо указать имя директории, то есть точку. Объединив все это вместе, увидим, что любой из следующих вызовов работает: File.list("C:\\."); или File.list("C:/."); Замечание: разделитель "/" работает точно так же, как и "\" во многих программах и системных вызовах Windows. Дело в том, что в прародителе DOS - операционной системе CP/M - не было директорий и, следовательно, разделителей в именах файлов. Прямой слэш "/" был уже задействован для передачи опций командам CP/M; обратный слэш "\" стали использовать как разделитель директорий в именах файлов, однако оболочка понимает и "/" для совместимости с другими операционными системами. *(Часть 7) В чем разница между различными форматами ZIP: ZIP, GZIPи PKZIP? [*] Zip - формат архивного файла, популярный на PC, который содержит несколько сжатых файлов внутри. GZIP - это GNU ZIP. Реально это подмножество формата ZIP с одним файлом внутри. В GZIP нельзя поместить целую директорию, а можно только один файл. PKZIP - набор коммерческих программ для создания файлов Zip. Все три используют алгоритм сжатия, основанный на LZ77. Этот метод сжатия также используется библиотекой ZLIB и, следовательно, графическим форматом PNG (который использует ZLIB). PNG - Portable Network Graphics - предоставляет свободную, не защищенную какими-либо патентами, замену GIF и TIFF. Альтернативная технология сжатия, LZW, защищена патентом Unisys. LZW используется в файлах GIF и в команде Unix'а compress. К счастью, будучи свободным от патентных зависимостей, LZ77 также дает лучшее сдатие, чем LZW. LZW - начальные буквы фамилий трех ученых, разработавших алгоритм (Lempel, Ziv, Welch). Основные классы (они находятся в java.util.zip), поддерживающие формат LZ77 - Deflater и Inflater. Они используются классами DeflaterOutputStream и InflaterInputStream. В пакете java.util.zip есть так же классы GZIPInputStream и ZipInputStream, унаследованные от InflaterInputStream. PKZIP - коммерческая программа для DOS, Windows и OS/2, продаваемая PKWARE. Файлы Jar (Java Archive) хранятся в формате ZIP, но существует одно отличие - не сохраняются атрибуты файлов. Известно, что некоторые версии WinZip неправильно поддерживают полный формат ZIP. Лучше использовать InfoZIP или PKZIP. *(Часть 8) Существуют ли пакеты в Java для управления HTML? [*] Смотрите ответ на Вопрос 13.14. *(Часть 8) Почему Dialogs не работают так, как я хочу? [*] Модальные диалоги (диалоговые окна, присутвующие пока на них не щелкнуть) проявляют глюкавость во многих браузерах и в JDK 1.0.2. Один из багов это когда диалог не становится активным окном, при выводе не экран. Многие из багов исправлены в JDK 1.1. (Часть 8) Где я могу получить информацию о классах sun.* в JDK? [ ] Эти классы поддерживают только функции в java.* иерархии. Они не являются частью API, и не будут работать в Java системах от поставщиков не Sun. Некоторые люди изменяли код и опубликовывали API для работы с этими классами, но вы будете использовать их на свой риск, и это может испортить что-либо без предупреждения. Плохо, что эти программы не были перенесены на обычную Java и будут работать только на JDK от Sun. По этой причине мы не реккомендуем использовать классы вне java.* когда вы используете JDK от других фирм. Если вы все-же настаиваете на том, что бы их использовать, можете посмотреть здесь: http://java.sun.com/products/api-overview/index.html http://www.parmly.luc.edu/javaudio/ http://www.users.interport.net/~mash/javamidi.html *(Часть 8) Как прочитать значения переменных ОС используя программу на Java? [*] Переменные окружения системы не используются в Java, так как они зависят от платформы. Mac-системы вообще не имеют таких переменных, например. У приложений Windows 95 не запускающихся из окна DOS нет переменных окружения. Используйте опции вместо них. В JDK 1.0 была допущена ошибка, из-за которой программистам самим приходилось устанавливать значение пере менной CLASSPATH. Это значение должно быть установлено в файле свойств. Создайте ваш собственный файл свойств(см. java.util.Properties) или укажи те опцией -D когда вы запускаете интерпретатор или JRE. Дополнительно на некоторых системах вы можете установить значение из коммандной строки, например: java -Dfoo=$foo MyClass (Unix) или java -Dfoo=%foo% MyClass (Win95/NT) Это установит значение "foo" в значение переменной окружения foo, и сделает это доступным в опциях System. Следите за тем, чтобы не было пробелов после -D или вокруг знака равенства("=") Внутри программы вы получите значение переменной foo таким образом: String env = System.getProperty("foo"); Можно поступить более просто, написав значение для foo в коммандной строке и прочитав ее как arg[0]. java MyClass %FOO% ; Win32 java MyClass $FOO ; Unix Наконец, вы можете запустить Runtime процесс для получения переменной окружения, если вы используете платформу, допускающую это. import java.io.*; import java.util.Properties; public class Main { public static void main(String[] argv) { Properties envVars = new Properties(); try { envVars.load( // используйте "set" в Windows Runtime.getRuntime().exec("/bin/env").getInputStream()); } catch (Throwable t) {t.printStackTrace();} System.out.println("\n\n"+argv[0]+" = <"+envVars.get(argv[0])+">"); } } Это не обычный подход к Java и это построится, в зависимости от платформы, которую вы используете. Смотрите Вопрос 10.6 для деталей. В Unix, комманда выводящая переменные ОС это "/usr/bin/env". В Windows 95, это "set". *(Часть 8) Как можно связать Java с базой данных Microsoft Access? [*] Используйте JDBC-ODBC мост. Это не слишком трудно в установке, но это требует особенного внимания к детялям. Мы предлагаем пример "шаг-за-шагом" из текста Линден(van der Linden) "Просто Java" упомянутом в разделе создателей этого документа. Заметьте, что версия JDK от Microsoft не поддерживает JDBC-ODBC доступ, из-за нестандартного интерфейса. JDBC FAQ можно найти на http://java.sun.com/products/jdbc/jdbc-frequent.html *(Часть 8) Я не могу сменить текущую рабочую директорию, не так-ли?. [*] Все верно. Это упущенная возможность является недосмотром, который мы надеемся исправить в будущем. ID этого бага 4156278, пожалуйста присоединяйтесь к JDC, и голосуйте, чтобы исправить это(и остальное). Изменение опции user.dir просто изменит текстовое значение, не воплощая изменения в жизнь. Существуют несколько обходов этого. * Запустите ваше приложение java как .bat или .sh файл и сделайте "cd" в нем(перед запуском, разумеется), если вы уверены в том, что все внешние процессы, запускаемые вашей программой могут быть запущены из этой директории. * Сделайте: exec("cd /home/wherever; externalApp.exe") в Unix, (этому, кажется, нет эквивалента на NT). * Вместо запуска .exe напрямую, запускайте (или записывайте на лету) .bat или .sh файл, который делает cd и затем запускает ваш .exe (это может создать проблему с возвращением обратно верного состояния). *(Часть 8) Как мне создать вектор числа? [*] Числа это обычные типы и следовательно не могут управляться векторным классом, который содержит объекты, вам придется откорректировать числа. Попробуйте это: int i =7; Vector holdsInts = new Vector(5,1); holdsInts.addElement(new Integer(i)); int j = ((Integer)holdsInts.elementAt(0)).intValue(); *(Часть 8) У меня есть несколько рабочих нитей. Я хочу, чтобы моя главная нить ожидала, пока остальные закончат работу, и действие начнется настолько скоро, насколько они все закончат работу. Я не знаю, какая из нитей закончит работу раньше остальных, поэтому я не иогу вызвать Thread.join на этой нити. Как мне быть? [*] Вам надо использовать механизм ожидание/сообщение, чтобы позволить любой из рабочих нитей разбудить вашу главную нить, когда первая закончит работу. *(Часть 8) Как мне получить случайные числа? [*] Если вам нужно быстро найти небольшое случайное число от 0.0 и до 1.0 double myrandom = Math.random(); // [0,1) Система обозначения "[0,1)" это обычное математическое варажение для "от нуля до .9999999 и т.п." Описания от Sun говорят, что это возвращает значение от 0 до 1, но исследование исходных кодов показывает, что они ошибаются. Однако, следуемые за присущими арифметической плавающей точке неточностями, случайный выбор N до 0.999999 может привести к ошибке. В JDK 1.2 входит другая версия nextInt, которая позволит более точно и безошибочно возвращать случайные числа, заданного интервала. Существует небольшая хитрость если вы используете JDK 1.1, и вам надо получить int в определенном интервале. Допустим, в интервале от 1 до 6, чтобы сэмулировать бросок костей или от 1 до 52 чтобы представить игральные карты. Класс Random имеет метод nextInt, который возратит любое число. import java.util.Random; Random r = new Random(); int i = r.nextInt(); Однако, есть почти 50% на то, что это число окажется не из правильного интервала. Так, вы просто получите значение abs() и затем разделите его на верхнюю границу интервала. int dice_throw = 1 + Math.abs(i) % 6; Исключением является то, что метод abs() грубо ошибается в присутствии Integer.MIN_VALUE (это тоже возращает отрицательный результат!). Поэтому, лучше выполнить логическое умножение(and) для достижения верных значений - при получении числа между определенными высшим и низшим значениями интервала (включительно): java.util.Random r = new java.util.Random(); int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low; Это решение сработает корректно "(почти) в 50% случаев" потому что существует на одно значение больше в отрицательных числах, чем в положительных в арифметических комлектах, какие использует Java. Для большинства целей, это предубеждение будет незначительным, а мы "и" nextInt() сводим их к нулю. Конечно, это маловероятно, что вам встретится эта ошибка, но вы же не хотите иметь критическую ситуацию, только из-за того, что упустили этот случай при тестировании своего приложения. Неприятная проблема это то, что с таким алгоритмом, младшие биты попадаются реже, чем старшие, при случайном выборе. Причина в том, что при операции деления (mod 2^n) младшие биты "пропадают" чаще, чем старшие. Можно предположить, что используя java.security.SecureRandom, получится более большая разбросанность случайных чисел, так как это использует "Криптографическую разбросанность" (Cryptograpic hash), но это также потребует более объемных вычислений от компьютера. *(Часть 9) Какие изменения произошли с java.util.Date при переходе от JDK 1.0 к JDK 1.1? [*] В JDK 1.1 класс java.util.Date был разделен для того, чтобы обеспечивать лучшую поддержку временных зон и интернациональных свойств. Классы, относящиеся к датам, выписаны ниже: 1. Класс Date представляет определенный момент времени, с точностью до миллисекунды. 2. Класс TimeZone это абстрактный класс, который представляет смещение часового пояса, а также вычисляет поправку при переходе на летнее время. 3. Класс SimpleTimeZone это единственный непосредственный подкласс класса TimeZone в JDK. Все что он определяет, это обычный часовой пояс с простым переходом на летнее время и периодом (этого перехода). 4. Класс Calendar это абстрактный класс для конвертирования объекта Date в набор целых чисел, таких как год, месяц, день и час (и обратно). 5. Класс GregorianCalendar это единственный непосредственный подкласс класса Calendar в JDK. Он производит преобразования из класса даты в целые числа (Date-to-fields) для общеупотребительной календарной системы. 6. Класс DateFormat это абстрактный класс, который позволяет Вам конвертировать класс Date в печатаемую строку с полями заданного вида (например dd/mm/yy или dd.MMM.yyyy). 7. Класс SimpleDateFormat это единственный непосредственный подкласс класса DateFormat в JDK. Он берет строку формата и либо разбирает строку, чтобы получить дату, либо берет дату и получает строку. По крайней мере один критик употребил термин "причудливая", когда описывал сложность связанных классов даты в Java, хотя остальные сказали бы "ломаная". Хорошей новостью является то, что в JDK 1.2 все общие проблемы были решены, и множество ошибок было исправлено в 1.1.4 и 1.1.6. Даже в 1.1.1 Вы можете избежать большинства наиболее распостраненных ошибок, всегда имея в виду, какую временную зону использует каждый класс. *(Часть 9) Что же в точности представляет из себя java.util.Date? [*] Класс java.util.Date хранит момент времени, как длинное целое (long integer), которое представляет из себя число миллисекунд, прошедших с 00:00:00 Jan 1, 1970 UTC (Coordinated Universal Time). Этот момент отсчета известен как "Epoch" ("Эпоха"). Это тот же момент отсчета (Epoch), который используется в системах UNIX. Более ранние даты, чем Epoch, представлены в виде отицательных чисел, отсчитываемых от 1/1/1970. Этой схемы достаточно, чтобы представлять даты от 292,269,053 B.C. (до нашей эры) до 292,272,993 A.D. (нашей эры) (64 бита покрывают диапазон от -9,223,372,036,854,775,808 до +9,223,372,036,854,775,807 миллисекунд). Заметьте, что версии, предшествующие JDK 1.2, GregorianCalendar не могут принимать значения раньше, чем 4716 B.C. Класс java.util.Date это легковесная (light-weight) конструкция, предназначенная только для хранения значения миллисекунд. Он используется для хранения и передачи момента времени. Другие задачи, такие как создание форматированной строки, вычисление дат, реализованы в других классах. *(Часть 9) Представляет ли класс java.util.Date верное значение UTC? [*] Нет, но его свершенно достаточно для большинства пользовательских задач, работющих с временем (time-keeping). На большинстве компьютеров он представляет только время с момента epoch как число, полученное из значения даты, содержащейся в аппаратном обеспечении. Если ваше аппаратное обеспечение синхронизировано с атомными часами, то ваше время представлено в UTC; большинство аппаратного обеспечения подразумевает, что день длится 24 часа, но есть еще 20 секунд (leap seconds), которые нужно добавлять к UTC, с тех пор как однажды это было сделано в 1972 году. *(Часть 9) Как я могу создать объект Date, который представляет из себя текущее время? [*] Значение по умолчанию объекта Date это текущее время. Таким образом следующий код создает объект даты, который содержит текущее время. Date now = new Date(); *(Часть 9) Я хочу создать строку, которая представляет из себя дату, в формате отличном от того, который возвращает метод java.util.Date.toString(). Должен ли я использовать Календарь (Calendar)? [*] Нет. Вместо того, чтобы создавать Календарь, вытягивать из него все необходимые поля и создавать строку, Вы можете использовать для ее создания SimpleDateFormat.format(). *(Часть 9) Почему все методы в java.util.Date отказываются работать? [*] Вероятнее всего потому, что исходный java.util.Date не был как положено извещен о временной зоне и "не был ответственен за интернационализацию". Чтобы научить этой временной зоне и интернационализировать потребуется добавление некоторой функциональности, которую можно увидеть в java.util.Calendar и некоторой функциональности из java.util.DateFormat. Если Вы находите комбинацию всех родственных классов даты сложной, то остается радоваться что они были разделены на разные классы. *(Часть 9) Мне совершенно не нужны интернационализация, информация о временной зоне, свехгибкий набор классов форматирования даты, есть что-нибудь еще, что позволило бы мне хранить даты и позволяло бы производить некоторые вычисления с ними? [*] Вы можете рассмотреть исользование класса BigDate, написанного Роди Грином (Roedy Green), и доступного в его весьма информативном голоссарии (ищите BigDate). Если Вы намерены сохранять результат в базе данных как объекты Date или TimeStamp. то Вам рекомендуется прочитать следующую ниже Часть о классе java.sql.Date. *(Часть 9) Если конструктор Date( String ) исключается из класса, то что я должен использовать вместо него? [*] Для создания объекта java.util.Date лучше всего использовать SimpleDateFormat.parse(). Конструктор класса Date, который принимает в качестве параметра строку, называется Date.parse( String). Метод Date.parse() имеет свои собственные правила для перевода 2-х цифрового года (как точку отсчета использует 1980 год) и другие ограничения, которые делают его мало значимым. Другие "тонкости" Date.parse(), которые не поддерживаются в SimpleDate не ускользнули от взгляда многих разработчиков. *(Часть 9) Конструктор Date(int year, int month, int date) и аналогичные конструкторы убираются из класса, что использовать вместо них? [*] Конструктор GregorianCalendar(int year, int month, int date) - вот его новая замена. Также годится метод Calendar.set( year, month, day ). Заметьте, что год в GregorianCalendar начинается с 1 A.D., а не с 1901, как в старом конструкторе класса Date. java.util.TimeZone *(Часть 9) Как я могу проверить, правильную ли временную зону использует моя JVM? [*] Следующий код выводит на экран ID текущей временной зоны по умолчанию. System.out.println( TimeZone.getDefault().getID() ); *(Часть 9) Значение TimeZone.getDefault не такое, как я ожидал(а). В чем проблема? [*] Значение временной зоны по умолчанию базируется на значении системного свойства "user.timezone". JVM предполагает установить это значение. В таких релизах, как JDK 1.1 значение user.timezone часто бывает не установлено, и таким образом TimeZone.getDefault() использует свое собственное встроенное "неитрализирующее" ("fallback") значение (по умолсанию когда нет значения по умолчанию). В дальнейших JDK 1.1 релизах и в JDK 1.2 установка значения user.timezone гораздо лучше и значение "fallback" теперь GMT (Greenwich Mean Time). Вплоть до JDK 1.1.3, значение "fallback" было "PST" (North American Pacific Timezone). *(Часть 9) Используют ли все стандартные объекты одно и то же Do all the standard objects use the значение временной зоны по умолчанию? [*] Нет, до JDK 1.2. В JDK 1.1, Date.toString() и Calendar используют значение TimeZone.getDefault() которое часто может быть неопределенным (смотрите предыдущий вопрос). В JDK 1.1, Calendar в SimpleDateFormat был установлен в 1-ю временную зону (для US это PST). System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() ); sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG ); System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() ); Calendar cal = Calendar.getInstance(); System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() ); Когда запускается в системе JDK 1.1.6, НЕ в Североамериканском Тихоокеанском времени и не во временной зое GMT, то результат будет : Timezone default = GMT Date format TZ = PST Calendar TZ = GMT Этот пример показывает 2 ошибки (bugs) значение user.timezone не определено, и оно установлено в GMT (смотрите обсуждение TimeZone.getDefault()) а так же показано, что DateFormat зависит от 1-го значения, которым является в данном случае PST. Если Вы не хотите использовать DateFormat в качестве Местной временной зоны, смотрите код представленный ниже. *(Секция 15) Почему < Windows RMI/мой java debugger/IDE/другое> зависает на несколько минут если мой Windows PC не подключен к Интернету? [*] Java имеет встроеную сетевую поддержку. Когда Java программа стартует, автоматически загружается Winsock DLL. Первое, что она пытается выполнить, это определить (resolve) полностью квалифицированное имя домена для машины "localhost". Если в Вашей системе не описано это имя, она будет пытаться запросить его у сервера имен Интернета, который обычно находится у Вашего провайдера Интернет (ISP). Поэтому система либо запросит Вас подключиться к провайдеру Интернет, либо будет ждать пока не истечет время попытки. Есть мнение, что можно избежать этой проблемы в Win95 дав определив в системе другой способ определять DNS имена. У меня это не работает. Отредактируйте файл hosts Вашей системы так, чтобы localhost и полное имя домена были оба определены. В Windows 95 файл hosts находитися в %windir%\HOSTS (например, C:\WINDOWS\HOSTS). В Windows NT файл hosts находится в: %windir%\System32\DRIVERS\ETC\HOSTS например, C:\WINNT\System32\DRIVERS\ETC\HOSTS). В Win95 есть ловушка, которая заключается в том, что если последняя запись не заканчивается символами carriage-return/line-feed, то файл hosts читается не до конца. Так, если система называется goober.best.com приведите файл hosts от вида 127.0.0.1 localhost к виду 127.0.0.1 goober.best.com localhost Файл может выглядеть следующим образом: # Hosts file 127.0.0.1 localhost 129.146.77.177 goober Другой способ состоит в том, чтобы установить PPP соединение с провайдером Интернет всякий раз, когда Вы будете запускать сетевые программы. Опыт некоторых людей говорит о том, что работа с сетью не совсем удовлетворительна под Windows95 с использованием Winsock 1.1, и время от времени необъяснимо глючит. Вы можете попытаться загрузить Winsock 2.0. Чтобы получить Winsock 2.0, Вы должны вытащить его из набора Microsoft Windows Sockets 2.0 Software Development Kit. Этот софт может быть получен со следующих адресов: http://www.microsoft.com/win32dev/netwrk/winsock2/ws295sdk.html или: ftp://ftp.microsoft.com/bussys/WinSock/winsock2/ Патчи, которые нужны для улучщения работы в сети уже есть в Win98. Другие Сетевые Вопросы *(Секция 15) Если я вызываю InetAddress.getByName() метод с аргументом IP - адресом в виде строки, типа "192.168.0.1", получаю на некоторых (но не на всех) платформах UnknownHostException. Код : Socket sock = new Socket("155.152.5.1", 23); бросает исключение. Почему? [*] Это платформенное различие, которое возникает из различной семантики лежащих в основе сетевых библиотек, и пофиксено в JDK 1.1. В Solaris и Windows NT, строка IP адреса работает только для тех адресов, которые имеют ассоциированное имя хоста. На Linux и Windows 95 строки IP адреса срабатывают всегда. Когда создается экземпляр InetAddress с IP адресом в качестве параметра, выполняется обратное DNS преобразование. Если IP адрес не ассоциирован с правильным именем хоста, то создание экзепляра класса InetAddress потерпит неудачу. Это является частью борьбы с DNS-spoofing (подмена DNS), и в JDK 1.1 работает потому что обратное преобразование не происходит пока имя хоста не запрошено. Так в JDK 1.1, InetAddress in = InetAddress.getByName("155.152.5.1"); [Note: Эту информацию нужно подтвердить. Сетевые гуру?] Другие сайты: У Microsoft есть несколько network-related патчей на их сайте http://www.microsoft.com/ *(Секция 15) Я хочу передать class файл всем тем желающим, кто использует мой апплет. Есть идеи насчет того как? [*] Ты должен использовать маленькую хитрость: разместить твой .class файл(ы) в .zip архиве и использовать метод showDocument() от URL. Некто, обращаясь к этому URL получит окно диалога, в котором он будет запрошен о сохранении файла на его локальном диске. Другие сайты: Вы можете увидеть это живьем и попробовать на себе на: http://www.best.com/~rmlynch/saveit.html *(Секция 15) Как заставить URLConnection работать через proxy firewall? Т.е. Как заставить Java приложение выполнять доступ к Web через прокси? [*] Это обычно нужно для любого сетевого доступа к другому домену. Вы должны задать runtime системе что Вы пытаетесь сделать используя аргументы командной строки когда запускаете программу. java -DproxySet=true -DproxyHost=SOMEHOST -DproxyPort=SOMENUM code.java Отметтье, что proxyPort является опциональным и по умолчанию равен 80. Без этого Вы увидите исключение типа java.net.UnknownHostException или java.net.NoRouteToHostException Установки прокси работают и для java.net.URLConnection, и для java.net.Sockets. Netscape'вская и IE'ая JVMs (виртуальные Java машины) (по крайней мере в версиях 4.х+) принимают установки прокси для апплетов из конфигурации прокси браузера. Вы можете также работать с прокси в проиложениях (не апплетах) добавив следующие строки // установите чтобы использовать прокси System.getProperties().put("proxySet", "true"); System.getProperties().put("proxyHost", "myproxy.server.name"); System.getProperties().put("proxyPort", "80"); Но как мне узнать имя прокси сервера? Этот код просто говорит Вам как можно получить URL соединение через прокси. Но так как это Ваш прокси сервер, то предполагается, что Вы знаете его имя. И не существует кода, который можно написать, который позволит произвольным
Секция 4 из 7 - Предыдущая - Следующая
Вернуться в раздел "Web-программирование" - Обсудить эту статью на Форуме |
Главная - Поиск по сайту - О проекте - Форум - Обратная связь |