fputcsv и коды новой строки

Разница между Control.Invoke() и Control.BeginInvoke() состоит в том, что

  • BeginInvoke() запланирует асинхронное действие в потоке GUI. Когда запланировано асинхронное действие, ваш код продолжается. Некоторое время спустя (вы точно не знаете, когда) ваше асинхронное действие будет выполнено
  • Invoke() выполнит ваше асинхронное действие (в потоке GUI) и будет ждать, пока ваше действие не будет завершено.

Логический вывод заключается в том, что делегат, который вы передаете в Invoke(), может иметь out-параметры или возвращаемое значение, в то время как делегат, который вы передаете в BeginInvoke(), не может (вы должны использовать EndInvoke для получения результатов ).

28
задан Community 23 May 2017 в 11:33
поделиться

5 ответов

// Writes an array to an open CSV file with a custom end of line.
//
// $fp: a seekable file pointer. Most file pointers are seekable, 
//   but some are not. example: fopen('php://output', 'w') is not seekable.
// $eol: probably one of "\r\n", "\n", or for super old macs: "\r"
function fputcsv_eol($fp, $array, $eol) {
  fputcsv($fp, $array);
  if("\n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) {
    fwrite($fp, $eol);
  }
}
38
ответ дан 28 November 2019 в 02:44
поделиться

Использование функции php fputcsv пишет только \ n и не может быть настроен. Это делает функцию бесполезной для среды Microsoft, хотя некоторые пакеты также обнаруживают новую строку linux.

Тем не менее, преимущества fputcsv заставили меня покопаться в решении заменить символ новой строки непосредственно перед отправкой в ​​файл. Это можно сделать путем потоковой передачи fputcsv в сборку во временном потоке php. Затем адаптируйте символы новой строки к тому, что вы хотите, и затем сохраните в файл. Как это:

function getcsvline($list,  $seperator, $enclosure, $newline = "" ){
    $fp = fopen('php://temp', 'r+'); 

    fputcsv($fp, $list, $seperator, $enclosure );
    rewind($fp);

    $line = fgets($fp);
    if( $newline and $newline != "\n" ) {
      if( $line[strlen($line)-2] != "\r" and $line[strlen($line)-1] == "\n") {
        $line = substr_replace($line,"",-1) . $newline;
      } else {
        // return the line as is (literal string)
        //die( 'original csv line is already \r\n style' );
      }
    }

        return $line;
}

/* to call the function with the array $row and save to file with filehandle $fp */
$line = getcsvline( $row, ",", "\"", "\r\n" );
fwrite( $fp, $line);
6
ответ дан 28 November 2019 в 02:44
поделиться

Как отметил webbiedave (thx!), Возможно, самый чистый способ - использовать потоковый фильтр.

Это немного сложнее, чем другие решения, но даже работает с потоками, которые не редактируются после записи в них (например, загрузка с использованием $handle = fopen('php://output', 'w');)

Вот мой подход:

class StreamFilterNewlines extends php_user_filter {
    function filter($in, $out, &$consumed, $closing) {

        while ( $bucket = stream_bucket_make_writeable($in) ) {
            $bucket->data = preg_replace('/([^\r])\n/', "$1\r\n", $bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

stream_filter_register("newlines", "StreamFilterNewlines");
stream_filter_append($handle, "newlines");

fputcsv($handle, $list, $seperator, $enclosure);
...
2
ответ дан 28 November 2019 в 02:44
поделиться

Я имел дело с похожей ситуацией. Вот решение, которое я нашел, которое выводит файлы CSV с оконными дружескими окончаниями.

http://www.php.net/manual/en/function.fputcsv.php#90883

Я не смог использовать, поскольку я пытаюсь Потоковая передача файла клиенту и не может использовать fseeks.

1
ответ дан 28 November 2019 в 02:44
поделиться

windows нуждается в \r\n как возврат строки / возврат каретки для отображения отдельных строк.

-1
ответ дан 28 November 2019 в 02:44
поделиться
Другие вопросы по тегам:

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