我有这个Python代码,可以将部分文件上传到服务器
import requests
file_path = "/Downloads/bim/7_LARD_90_99.ifc"
range_start = 0
range_end = 299999
headers = {
"X-API-KEY": "xxx-xxx-xxx",
"Content-Disposition": "form-data; filename=7_LARD_90_99.ifc",
"Content-Type": "application/octet-stream",
"Content-Range": f"bytes {range_start}-{range_end}/16531527"
}
try:
with open(file_path, "rb") as file:
file_chunk = file.read(range_end - range_start + 1)
response = requests.post(
"https://field.dalux.com/service/api/1.0/projects/xxxxxxxx/file_areas/yyyyyyyy/upload/zzzzzzzzzz",
headers=headers,
data=file_chunk
)
print("Response Status Code:", response.status_code)
print("Response Content:", response.text)
except Exception as e:
print("An error occurred:", e)
这段代码运行良好。我正在尝试将其转换为 Powershell,但 Powershell 似乎处理不同的请求,并且显示不同的正文大小(这会在 API 上引发异常)。
$file = "/Downloads/bim/7_LARD_90_99.ifc"
$rangeStart = 0
$rangeEnd = 299999
$headers = @{
"X-API-KEY" = "xxx-xxx-xxx"
"Content-Disposition" = "form-data; filename=7_LARD_90_99.ifc"
"Content-Type" = "application/octet-stream"
"Content-Range" = "bytes $rangeStart-$rangeEnd/16531527"
}
try {
$fileChunkBytes = [System.IO.File]::ReadAllBytes($file)[$rangeStart..$rangeEnd]
Write-Host $fileChunkBytes.Length
$response = Invoke-RestMethod -Method Post `
-Uri "https://field.dalux.com/service/api/1.0/projects/xxxxxxx/file_areas/yyyyyyy/upload/zzzzzzzzz" `
-Headers $headers `
-ContentType "application/octet-stream" `
-Body $fileChunkBytes `
-UseBasicParsing
Write-Host "Response Status Code: $($response.StatusCode)"
Write-Host "Response Content:"
$response.Content
} catch {
Write-Host "An error occurred: $_"
}
我从 API 收到此错误:
{
"httpStatusCode": 400,
"errorCode": "E40004",
"errorCodeMessage": "HeaderValidationFailed",
"message": "Content-Range header size 300000 is not the same as the content size 901216",
"logTime": "2024-02-08T16:02:46.3439873Z"
}
这里的问题出在 Invoke-RestMethod 方法中。
文件块的解析出现问题。相反,我让它与 WebRequest 一起使用
$fileStream = [System.IO.File]::OpenRead($filePath)
$contentLength = $fileStream.Length
$position = 0
# Calculate the size of the next chunk
$chunkSize = [Math]::Min($chunk_size, $contentLength - $position)
# Read the next chunk from the file
$chunkBytes = New-Object byte[] $chunkSize
$bytesRead = $fileStream.Read($chunkBytes, 0, $chunkSize)
# Define the headers for the HTTP request
$headersUpload = @{
"X-API-KEY" = $apiKey
"Content-Disposition" = "form-data; filename=$fileName"
"Content-Type" = "application/octet-stream"
"Content-Range" = "bytes $position-$($position + $bytesRead - 1)/$contentLength"
"Content-Length" = $bytesRead
}
# Create a WebRequest object
$webRequest = [System.Net.WebRequest]::Create($uri)
$webRequest.Method = "POST"
foreach ($key in $headersUpload.Keys) {
$webRequest.Headers.Add($key, $headersUpload[$key])
}
# Get the request stream
$requestStream = $webRequest.GetRequestStream()
# Write the chunk to the request stream
$requestStream.Write($chunkBytes, 0, $bytesRead)
# Close the request stream
$requestStream.Close()
# Get the response
$response = $webRequest.GetResponse()
$response.Close()