Как я служу большому файлу для загрузки с Perl?

class StackADT(var capacity: Int) {

    private var top = -1
    private val stack: ArrayList = ArrayList(capacity)

    fun push(element: T) {
        if (top == capacity)
            throw Exception("Overflow occurred in stack!!")
        top++
        stack.add(element)
    }
    ...

Вы можете проверить здесь: Kotlin Playground

Другой способ:

var stack = arrayOfNulls(capacity) as Array
7
задан Community 23 May 2017 в 12:33
поделиться

8 ответов

Если Вы просто хотите хлебать вход для вывода, это должно добиться цели.

use Carp ();

{ #Lexical For FileHandle and $/ 
  open my $fh, '<' , '/path/to/file.txt' or Carp::croak("File Open Failed");
  local $/ = undef; 
  print scalar <$fh>; 
  close $fh or Carp::carp("File Close Failed");
}

Я предполагаю в ответ на, "Делает Perl, имеют PHP ReadFile Equivelant", и я предполагаю, что мой ответ был бы, "Но ему действительно не нужно один".

Я использовал ручной Файл PHP средства управления IO, и они - боль, Perls настолько просты в использовании для сравнения, что выход из оболочки для единой функции кажется излишеством.

Кроме того, Вы могли бы хотеть посмотреть на X-SendFile поддержка, и в основном отправляет заголовок на Ваш веб-сервер для сообщения этого что файл отправить: http://john.guen.in/past/2007/4/17/send_files_faster_with_xsendfile/ (принимающий, конечно, это имеет полномочия достаточно для доступа к файлу, но файл просто НЕ обычно доступен через стандартный URI),

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

Альтернативные блоки использования

Следующий улучшенный код читает данный файл в блоках 8 192 символов, который является намного большей эффективной памятью, и получает пропускную способность, достойно сопоставимую с моим дисковым уровнем чтения сырых данных. (Я также указал на него на/dev/full для соответствий и хихиканья и получил здоровую 500mb/s пропускную способность, и это не съело все мои поршни, так, чтобы было хорошо),

{ 
    open my $fh , '<', '/dev/sda' ; 
    local $/ = \8192; # this tells IO to use 8192 char chunks. 
    print $_ while defined ( $_ = scalar <$fh> ); 
    close $fh; 
}

Применение jrockways предложения

{ 
    open my $fh , '<', '/dev/sda5' ; 
    print $_ while ( sysread $fh, $_ , 8192 ); 
    close $fh; 
}

Это буквально удваивает производительность... и в некоторых случаях, получает меня лучшая пропускная способность, чем DD O_o.

7
ответ дан 6 December 2019 в 15:32
поделиться

Функция readline вызвана readline (и может также быть записан как <>).

Я не уверен, какую проблему Вы имеете. Возможно, это для циклов лениво не оценено (который они не). Или, возможно, Связь:: Файл завинчивает что-то? Так или иначе идиоматический Perl для чтения файла строка за один раз:

open my $fh, '<', $filename or die ...;
while(my $line = <$fh>){
   # process $line
}

Никакая потребность использовать Связь:: Файл.

Наконец, Вы не должны обрабатывать этот вид вещи сами. Это - задание для веб-платформы. При использовании Катализатора (или HTTP::Engine), Вы просто сказали бы:

open my $fh, '<', $filename ...
$c->res->body( $fh );

и платформа автоматически служила бы данным в файле эффективно. (Используя stdio через readline не хорошая идея здесь, лучше считать файл в блоках от диска. Но кто заботится, это абстрагировано!)

2
ответ дан 6 December 2019 в 15:32
поделиться

Вы могли использовать мой Sys:: модуль Sendfile. Это, должно быть высокоэффективным (поскольку это использует sendfile под капотом), но не совсем портативный (только Linux, FreeBSD и Солярис в настоящее время поддерживаются).

2
ответ дан 6 December 2019 в 15:32
поделиться

Когда Вы говорите, что "это не заставляет браузер запрашивать загрузку" - каков "браузер"?

Различные браузеры ведут себя по-другому, и IE особенно преднамерен, он проигнорирует заголовки и решит для себя, что сделать на основе чтения нескольких первых Кбит файла.

Другими словами, я думаю, что Ваша проблема может быть в клиентском конце, не конце сервера.

Попытайтесь лгать "браузеру" и сказать ему, что файл имеет приложение типа/octet-stream. Или почему не только архивируют файл, тем более, что это настолько огромно.

1
ответ дан 6 December 2019 в 15:32
поделиться

Не использовать for/foreach (<$input>) потому что это читает целый файл сразу и затем выполняет итерации по нему. Использовать while (<$input>) вместо этого. sysread решение хорошо, но sendfile лучшее мудрое производительностью.

1
ответ дан 6 December 2019 в 15:32
поделиться

Я успешно сделал это путем сообщения браузера, это имело приложение типа/octet-stream вместо текста/плоскости типа. По-видимому, большинство браузеров предпочитает отображать текст/плоскость, встроенный вместо того, чтобы дать пользователю диалоговую опцию загрузки.

Это технически лжет браузеру, но это делает задание.

0
ответ дан 6 December 2019 в 15:32
поделиться

Ответ на (исходный) вопрос ("Делает Perl, имеет эквивалент PHP's readline() функция...?"), ответ является "синтаксисом угловой скобки":

open my $fh, '<', '/path/to/file.txt';
while (my $line = <file>) {
    print $line;
}

Получение довольной длины с этим методом не обязательно легко, тем не менее, таким образом, я рекомендовал бы остаться с Tie::File.


Примечание:

Используя:

for my $line (<$filehandle>) { ... }

(как я первоначально записал), копирует содержание файла к списку и выполняет итерации по этому. Используя

while (my $line = <$filehandle>) { ... }

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


Ответ на (обновленный) вопрос ("Делает Perl, имеет эквивалент PHP's readfile() функция...?"), ответ хлебает. Существует несколько синтаксисов, но Perl6::Slurp кажется, текущий предпочтительный модуль.

Подразумеваемый вопрос ("почему браузер не запрашивает загрузку прежде, чем захватить весь файл?"), абсолютно не имеет никакого отношения к тому, как Вы читаете в файле и всем, чтобы сделать, с каким думает браузер, хорошая форма. Я предположил бы, что браузер видит тип пантомимы и решает, что знает, как отобразить простой текст.


Смотря более тесно на проблему Довольного Расположения, я не забываю испытывать подобные затруднения из-за Довольного Расположения игнорирования IE. К сожалению, я не могу помнить обходное решение. IE имеет долгую историю проблем здесь (старая страница, относится к IE 5.0, 5.5 и 6.0). Для разъяснения, однако, я хотел бы знать:

  1. На какую ссылку Вы использующий для указания на этот большой файл (т.е. Вы использующий нормальное a href="perl_script.cgi?filename.txt свяжитесь или Вы используете JavaScript некоторого вида)?

  2. Какую систему Вы используете для фактического обслуживания файла? Например, веб-сервер устанавливает свою собственную связь с другим компьютером без веб-сервера, и затем копирует файл в веб-сервер и затем отправляет файл конечному пользователю, или пользователь устанавливает связь непосредственно с компьютером без веб-сервера?

  3. В исходном вопросе Вы записали, что "это не заставляет браузер запрашивать загрузку прежде, чем захватить весь файл", и в комментарии Вы записали, что "Я все еще не добираюсь, подсказка загрузки для файла до всего этого загружается". Это означает, что файл отображен в браузере (так как это - просто текст), что после того, как браузер загрузил весь файл, который Вы получаете, "где Вы хотите сохранить этот файл" подсказка или что-то еще?

У меня есть чувство, что существует шанс, HTTP-заголовки становятся разделенными в какой-то момент или что заголовок управления Кэша становится добавленным (который, по-видимому, может доставить неприятности).

1
ответ дан 6 December 2019 в 15:32
поделиться

Самый эффективный способ служить большому файлу для загрузки зависит от веб-сервера, который Вы используете.

В дополнение к @Kent Fredric X-Sendfile предложение:

Сделанные правильно Загрузки файла имеют некоторые ссылки, которые описывают, как сделать это для Apache, lighttpd (mod_secdownload: безопасность через поколение URL), nginx. Существуют примеры в PHP, Ruby (направляющие), Python, который может быть принят для Perl.

В основном это сводится к:

  1. Настройте пути и полномочия для Вашего веб-сервера.
  2. Генерируйте действительные заголовки для перенаправления в Вашем приложении Perl (Content-Type, Content-Disposition, Content-length?, X-Sendfile или X-Accel-Redirect, и т.д.).

Существуют, вероятно, модули CPAN, плагины веб-платформ, которые делают точно это, например, @Leon упомянутый Timmermans Sys::Sendfile в его ответе.

0
ответ дан 6 December 2019 в 15:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: