Модераторы: javastic, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с функцией skip, Как заставить skip работать быстрее? 
:(
    Опции темы
Brodyaga
Дата 3.3.2008, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Всем здравствуйте! У меня проблема.. Мне нужно считывать данные с конца файла, но функция skip слишком долго работает. Делаю я это так...
Код

    DataInputStream fileInputStream=fileConnection.openDataInputStream();
    fileInputStream.skip(1300000);
    int x=fileInputStream.readInt();
        
    fileInputStream.close();
        
    return String.valueOf(x);


Приходится ждать несколько минут... Как сделать так, чтобы можно было быстро начать читать с конца файла? Есть ли какие-нибудь средства произвольного доступа к файлу?
PM MAIL   Вверх
math64
Дата 3.3.2008, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Нужно порезать файл на кусочки известной длины и сразу открывать нужный кусок.
PM   Вверх
Brodyaga
Дата 3.3.2008, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Подругому нельзя? Есть ли классы произвольного доступа к файлам?
И если резать, то как? Программно или перед переносом на телефон вручную?
PM MAIL   Вверх
math64
Дата 3.3.2008, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Конечно, для реализации getResourceAsStream() нужно иметь произвольный доступ в файле и уметь раскрывать ZIP. Но в стандартном API этого нет. В J2ME-читалках книжки обычно режут кусками 16K. Программу для нарезки можно найти в интернете или написать самому.
PM   Вверх
Brodyaga
Дата 3.3.2008, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Тоесть резать программно? закидываю на телефон целый файл и джава прогой режу его и помещаю в память? так чтоли? можете скинуть ссылку на какойнить пример?
PM MAIL   Вверх
Shushpanchik
Дата 4.3.2008, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 17.7.2007
Где: Россия, г. Пенза

Репутация: 1
Всего: 1



Цитата(Brodyaga @ 3.3.2008,  08:41)
Всем здравствуйте! У меня проблема.. Мне нужно считывать данные с конца файла, но функция skip слишком долго работает. Делаю я это так...
Код

    DataInputStream fileInputStream=fileConnection.openDataInputStream();
    fileInputStream.skip(1300000);
    int x=fileInputStream.readInt();
        
    fileInputStream.close();
        
    return String.valueOf(x);


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

Сталкивался с такой же проблемой. Решена она была так - взял код метода InputStream.skipBytes() из JDK, написал в своем классе точно такой же, но с увеличенным размером буфера:
Код

private static final int SKIP_BUF_SIZE = 20480;

/**
 * Метод аналогичен методу <CODE>InputStream.skip(long)</CODE>, но использует больший размер буфера.
 * Пропускает указанное количество байтов из входного потока <CODE>m_disSounds</CODE>.
 * @param n количество байт, которые нужно пропустить в потоке <CODE>m_disSounds</CODE>.
 * @throws IOException если произошла ошибка ввода-вывода.
 * @see <CODE>InputStream.skip(long)</CODE>
 */
private void skipBytes(long n) throws IOException {
  long remaining = n;
  int nr;
  byte[] skipBuffer = new byte[SKIP_BUF_SIZE];
  while (remaining > 0) {
    nr = m_disSounds.read(skipBuffer, 0, (int) Math.min(SKIP_BUF_SIZE, remaining));
    if (nr < 0) {
      break;
    }
    remaining -= nr;
  }    
}


Размер буфера был определен эмпирическим путем. У меня файлы используются 700-1000Кб, поэтому размер буфера в 20 Кб оказался оптимальным с точки зрения затрачиваемой памяти и получаемого быстродействия.
PM MAIL WWW ICQ   Вверх
Brodyaga
Дата 4.3.2008, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Я уже у себя так делал... но всеровно спасибо! Просто думал может есть способ другой... какогонит произвольного доступа... без постонного считывания в массив. А как вернуть поток на начало?
PM MAIL   Вверх
Brodyaga
Дата 28.5.2008, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Как нибудь можно всётаки перемещаца на начало файла с помощью skip или другими средствами БЕЗ нового открытия потока на файл, как показано ниже:
Код

DataInputStream dataInputStream;
int shiftFirst;

dataInputStream=new DataInputStream(fileConnection.openInputStream());
dataInputStream.skipTurbo(fileConnection.fileSize()-4);
shiftFirst=dataInputStream.readIntCorrect();
dataInputStream.close();
            
dataInputStream=new DataInputStream(fileConnection.openInputStream());
......
......
......

PM MAIL   Вверх
Brodyaga
Дата 3.6.2008, 06:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Ну неужели никто не знает и не сталкивался с этим?! :( Помогите плиз, очень надо...
PM MAIL   Вверх
Дрон
Дата 4.6.2008, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 92



А в J2ME нет класса RandomAccessFile?

Это сообщение отредактировал(а) Дрон - 4.6.2008, 15:06


--------------------
Да. Именно так.
PM   Вверх
Dummy
Дата 4.6.2008, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Нет. Все операции с файлом потоковые и односторонние.

Добавлено через 4 минуты и 20 секунд
Brodyaga, можно попробовать сделать mark() на InputStream в позиции, куда надо будет откатиться, а в нужный момент вызвать reset(). Правда, в этом случае нужно быть готовым получить IOException, если в твоей реализации JSR-75 mark() / reset() не поддерживается.

Добавлено через 8 минут и 30 секунд
А можно даже и не ждать IOException, а просто спросить у потока: InputStream.markSupported(). Если вернет true - счастье, можно использовать подход, про который я выше написал. Если false - увы, придется открывать новый поток каждый раз.

Кстати, а что ты имеешь против открытия нового потока? Считаешь, что слишком накладная операция? Не думаю, что настолько, чтобы бояться лишний раз открыть поток smile 

PM MAIL   Вверх
eugine_s
Дата 4.6.2008, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 14.11.2007
Где: Киев

Репутация: 17
Всего: 17



Цитата(Dummy @  4.6.2008,  15:05 Найти цитируемый пост)
Кстати, а что ты имеешь против открытия нового потока? Считаешь, что слишком накладная операция? Не думаю, что настолько, чтобы бояться лишний раз открыть поток


Новый поток к файлу - новый запрос "Разрешить читать / писать данные из файла?"



Это сообщение отредактировал(а) eugine_s - 4.6.2008, 15:17
PM MAIL   Вверх
Dummy
Дата 4.6.2008, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Цитата

Новый поток к файлу - новый запрос "Разрешить читать / писать данные из файла?"


Если политика безопасности на устройстве не дает разрешить чтение до конца сессии или от первого обращения до удаления, то да, ты прав. А так как мы должны думать о переносимости между устройствами, и в общем случае запрос на разрешение может появляться при каждом обращении, то ты и подавно прав  smile 

Поэтому вижу только один выход. Проверить, поддерживается ли mark()-reset() на файловом потоке, если поддерживается - радоваться и использовать. Если нет - можно запесочить своего наследника от InputStream, который будет поддерживать mark() - reset() за счет кэширования считанных данных. Увы, для случая, если мы находимся в конце файла, мы сможем откатиться в начало, только если весь файл вычитать в память. Для больших файлов не решение, но если же нужно откатываться только в пределах разумного диапазона, например, десяток-другой килобайт, то это поможет.

PM MAIL   Вверх
Brodyaga
Дата 5.6.2008, 06:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: 2
Всего: 2



Цитата

А в J2ME нет класса RandomAccessFile?


В том то и дело что нет...

Цитата

Кстати, а что ты имеешь против открытия нового потока? Считаешь, что слишком накладная операция? Не думаю, что настолько, чтобы бояться лишний раз открыть поток smile 

Как раз таки настолько... Если бы было не настолько я бы не искал решения без новых коннекций..

Цитата

Новый поток к файлу - новый запрос "Разрешить читать / писать данные из файла?"


Мидлет подписан... Тут дело в том что эта операция очень ресурсоёмкая

Цитата

Поэтому вижу только один выход. Проверить, поддерживается ли mark()-reset() на файловом потоке, если поддерживается - радоваться и использовать.


А от чего зависит возможность поддержки потоком mark-reset ? Из разговора я понял что не все потоки могут его поддерживать? какие могут, а какие нет?
PM MAIL   Вверх
Dummy
Дата 5.6.2008, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Цитата

Тут дело в том что эта операция очень ресурсоёмкая


Почему ты так думаешь? Делал какие-то конкретные замеры? Какие именно ресурсы так требует эта безобидная операция?

Цитата

А от чего зависит возможность поддержки потоком mark-reset ? Из разговора я понял что не все потоки могут его поддерживать? какие могут, а какие нет?


От конкретной реализации JSR-75. В принципе, для файлов не составляет труда реализовать mark() на неограниченный размер и reset() без всяких буферов в памяти, просто используя платформенный seek(), - как раз то, что тебе нужно. Но вот реализовано это или нет - точно сказать нельзя, надо проверять в каждом конкретном случае. Для этого и придумали InputStream.markSupported().

Это сообщение отредактировал(а) Dummy - 5.6.2008, 09:04
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.1021 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.