Загрузите файл с FTP-сервера со списком путей и загрузите каждый указанный файл

Сейчас я работаю над проектом, где мне нужно загрузить изображения с ftp-сервера, чтобы разместить их на веб-сайте.

Путь к изображениям находится в текстовом файле, который заархивирован на сервере. Путь для каждого изображения выглядит следующим образом:

pc33c1_26126_08_hd.jpg /photos/pvo/transfertvo/photos/pc33c1/pc33c1_x48_08_hd.jpg 1a71ffb90de7628b8b1585b7e85c68e7

Способ получения фотографий должен выглядеть так:

get /photos/pvo/transfertvo/photos/pc33c1/pc33c1_x48_08_hd.jpg pc33c1_26126_08_hd.jpg

Этот пример был предоставлен компанией, которая размещает изображения.

Когда я подключаюсь к ftp с помощью PowerShell, доступны две директории: одна, в которой находится zip-файл, и другая, которая кажется пустой. Когда вы смотрите на пути в файле .txt, вы можете ясно видеть, что изображения на самом деле находятся во втором каталоге, который кажется пустым. Когда вы используете команду get в PowerShell, вы можете загрузить картинку, но только одну за другой (и есть сотни картинок, которые нужно загрузить).

Я попытался написать сценарий PowerShell, который просматривает файл .txt и «берет» URL-адрес, необходимый для поиска изображения. Сначала мне нужно подключиться к FTP, но следующий код не работает:

$FTPServer = "ftp.example.com"$FTPUsername = "user"$FTPPassword = "pass"$credential = New-Object System.Net.NetworkCredential($FTPUsername, $FTPPassword)

$FTP = [System.Net.FtpWebRequest]::Create($FTPServer)

$FTP.Credentials=$credential
$FTP.UseBinary = 1
$FTP.KeepAlive = 0

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

$f = Get-Content "photos.txt"$i = 0

foreach ($line in $f) {

$fields = $line.Split("`t")

$First = $fields[0]
$Second = $fields[1]
$Third = $fields[2]
$number = $i++

$url = $Second +" "+ $First

write-host "Title is: "$First
write-host "Path is: "$Second
write-host "Hash is: "$Third
write-host "Number is: " $number
Write-Host "This is the url: " $url
get $url
Write-Host ""}

Что это должно сделать, он должен пройти через массив и разбить каждую строку, чтобы создать URL-адрес изображения с соответствующим именем. Но без связи это ничего не делает.

Можно ли запустить сценарий внутри PowerShell FTP, чтобы загрузить все эти изображения одновременно?

Я также пытался написать сценарий PHP, но я столкнулся со многими проблемами. Вот код:

<?php

$ftp_server = 'ftp.example.com';
$ftp_user_name = 'user';
$ftp_user_pass = 'pass';
$remoteFilePath = '/data/photos.txt.zip';
$localFilePath = $_SERVER['DOCUMENT_ROOT']."/path/";

// set up basic connection
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

if ((!$conn_id) || (!$login_result)) {
echo 'FTP connection has failed! Attempted to connect to '. $ftp_server. ' for user '.$ftp_user_name.'.';
}else{
echo 'FTP connection was a success.<br>';
$directory = ftp_nlist($conn_id,'');
echo '<pre>'.print_r($directory,true).'</pre>';

$contents = ftp_nlist($conn_id, "/data/");
var_dump($contents);

$bla = ftp_nlist($conn_id, "/photos/");
var_dump($bla);

ftp_pasv($conn_id, true);

if (ftp_get($conn_id, $localFilePath.'/photos.txt.zip', $remoteFilePath, FTP_BINARY)) {

echo "File has been downloaded!!";
return true;

} else {
echo "fail ... ";
echo "Connected has be stopped!!";
return false;
}
}
ftp_close($conn_id);

?>

Это подключается к FTP, проверяет соединение и загружает zip-файл на локальный компьютер.

<?php

// assuming file.zip is in the same directory as the executing script.
$file = 'photos.txt.zip';

// get the absolute path to $file
$path = pathinfo(realpath($file), PATHINFO_DIRNAME);

$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
// extract it to the path we determined above
$zip->extractTo($path);
$zip->close();
echo " $file extracted to $path";
} else {
echo "Couldn't open $file";
}

?>

Этот разархивирует ранее загруженную zip-папку в том же месте. Последний фрагмент кода, который пытается найти путь и загрузить изображения, не работает:

header("Content-Type: text/html; charset=UTF-8");
$lines = file("photos.txt");
$dir = "local\\path\\to\\file\\";

foreach ($lines as $line) {
$parts = explode("\t", $line);
$something = $parts[1];
$somethingelse = $parts[0];
$var1 = $ftp_server.$something;

file_put_contents($dir, file_get_contents($var1));
}

Он успешно разбивает массив и получает URL, но он не загружает изображения, а вместо этого дает мне ошибки:

file_get_contents (...) failed to open stream: No such file or directory in...

file_get_contents (...) failed to open stream: Permission denied in...

Я попытался изменить все разрешения, как предложено в некоторых других темах, но безрезультатно.

Я также нашел похожую тему Вот, но предложенное решение устарело и совсем не помогло.

Я должен сказать, что я довольно новичок в PowerShell и PHP, и я был бы признателен за любую помощь, которую вы можете предоставить.

2

Решение

Я закончил с использованием PHP. Вот рабочий код:

1- скачать почтовый индекс

$ftp_server = 'ftp.example.com';
$ftp_user_name = 'user';
$ftp_user_pass = 'psasword';
$remoteFilePath = '/data/photos.txt.zip';
$localFilePath = $_SERVER['DOCUMENT_ROOT']."/images";


// set up basic connection
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

if ((!$conn_id) || (!$login_result)) {
echo 'FTP connection has failed! Attempted to connect to '. $ftp_server. ' for user '.$ftp_user_name.'.';
}else{
echo 'FTP connection was a success.<br>';
$directory = ftp_nlist($conn_id,'');
echo '<pre>'.print_r($directory,true).'</pre>';

$contents = ftp_nlist($conn_id, "/data/");
var_dump($contents);

$photos = ftp_nlist($conn_id, "/photos/");
var_dump($photos);


ftp_pasv($conn_id, true);

if (ftp_get($conn_id, $localFilePath.'/ddda-photos.txt.zip', $remoteFilePath, FTP_BINARY)) {

echo "File has been downloaded!!";
return true;

} else {
echo "fail ... ";
echo "Connected has be stopped!!";
return false;

}

}

2- Распакуйте файл

// assuming file.zip is in the same directory as the executing script.
$file = 'photos.txt.zip';

// get the absolute path to $file
$path = pathinfo(realpath($file), PATHINFO_DIRNAME);

$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
// extract it to the path we determined above
$zip->extractTo($path);
$zip->close();
echo "$file extracted to $path";
} else {
echo "Couldn't open $file";
}

3- Прочитайте текстовый файл и загрузите изображения

//So it doesn't time out
set_time_limit(0);

$ftp_server = 'ftp.example.com';
$ftp_user_name = 'user';
$ftp_user_pass = 'password';

$lines = file("photos.txt");
$dir = "F://test/";

//Goes through the file and separates name path and hash
foreach ($lines as $line) {
$parts = explode("\t", $line);
$imagePath = $parts[1];
$imageName = $parts[0];
$var1 = $ftp_server.trim($imagePath,'/');

$ftpUrl = 'ftp://'.$ftp_user_name.':'.$ftp_user_pass.'@'.$ftp_server.'/'.$imagePath;

// ftp url dump to be sure that something is happening
var_dump($ftpUrl);

$curl = curl_init();
$fh   = fopen($dir.$imageName, 'w');
curl_setopt($curl, CURLOPT_URL, $ftpUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);

fwrite($fh, $result);
fclose($fh);
curl_close($curl);
}

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

Надеюсь, что это помогает кому-то с той же проблемой.

1

Другие решения

Вы, кажется, ожидаете, что после «подключения» к FTP с помощью FtpWebRequest, get Команда каким-то образом волшебным образом получит файлы с FTP-сервера.

Это предполагает так много вещей, которые просто не соответствуют действительности, что трудно догадаться, с чего начать объяснение.

  • Нет никаких get в PowerShell. Это обычная команда в клиентах FTP.
  • FtpWebRequest не могу просто подключиться. Класс предназначен для выполнения одноразовых заданий, таких как загрузка файлов и т. Д. Не для создания постоянного соединения.
  • и т. д. и т. д.

По сути, вам нужно скачать файл списка с помощью WebRequest (FtpWebRequest), а затем повторите то же самое для каждого файла:

$credentials = New-Object System.Net.NetworkCredential("username", "password")

$baseUrl = "ftp://ftp.example.com"$listPath = "/remote/path/list.txt"$listUrl = $baseUrl + $listPath

Write-Host "Retrieving file list from $listPath..."
$listRequest = [Net.WebRequest]::Create($listUrl)
$listRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$listRequest.Credentials = $credentials

$lines = New-Object System.Collections.ArrayList

$listResponse = $listRequest.GetResponse()
$listStream = $listResponse.GetResponseStream()
$listReader = New-Object System.IO.StreamReader($listStream)
while (!$listReader.EndOfStream)
{
$line = $listReader.ReadLine()
$lines.Add($line) | Out-Null
}
$listReader.Dispose()
$listStream.Dispose()
$listResponse.Dispose()

foreach ($line in $lines)
{
$fields = $line.Split("`t")
$file = $fields[0]
$remoteFilePath = $fields[1]

Write-Host "Downloading $remoteFilePath..."$fileUrl = $baseUrl + $remoteFilePath
$localFilePath = $file

$downloadRequest = [Net.WebRequest]::Create($fileUrl)
$downloadRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$downloadRequest.Credentials = $credentials

$downloadResponse = $downloadRequest.GetResponse()
$sourceStream = $downloadResponse.GetResponseStream()
$targetStream = [System.IO.File]::Create($localFilePath)
$buffer = New-Object byte[] 10240
while (($read = $sourceStream.Read($buffer, 0, $buffer.Length)) -gt 0)
{
$targetStream.Write($buffer, 0, $read);
}
$targetStream.Dispose()
$sourceStream.Dispose()
$downloadResponse.Dispose()
}

Код в основном такой же, как мой ответ на PowerShell FTP скачать файлы и подпапки, за исключением того, что он получает список файлов из файла, а не из списка каталогов.

0

По вопросам рекламы [email protected]