• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

LrHttp.post(): Using file:read() instead of LrFileUtils.readFile() doesn't work

Explorer ,
Jan 31, 2017 Jan 31, 2017

Copy link to clipboard

Copied

I'm using Lr 6.8 / Win10.

I have running code that uploads photo/videos to a WebService via LrHttp.post(). Basicly, the code is:

function PSUploadAPI.uploadPictureFile(...)

...

     local respBody, respHeaders = LrHttp.post(h.serverUrl .. h.uploadPath, LrFileUtils.readFile(srcFilename), postHeaders, 'POST', timeout, fileSize)

...

Now, someone tried to upload a 11 minute FullHD/30fps AVCHD Video with a filesize of 2GB and ended up with:

Internal error: 'Attempt to seek past end of file'

So, I assume there is a size limit for LrFileUtils.readFile(). Looking for a solution I found this thread answered by John:

How to avoid LrStringUtils.encodeBase64 and LrFileUtils.readFile to block the main thread?

I reworked the code accordingly to use file:read():

local readFiles = {}

local function openFile(filename)

    readFiles[filename] = io.open(filename, "rb")

end

   

local function readFileChunk(filename, nBytes)

    if not readFiles[filename] then

        writeLogfile(4, string.format("readFileChunk(%s, %d): file not opened\n", filename, nBytes))

        return false

    end

    local readBuf = readFiles[filename]:read(nBytes)

    if readBuf then

        writeLogfile(4, string.format("readFileChunk(%s, %d) returns %d Bytes\n", filename, nBytes, #readBuf))

    else

        writeLogfile(4, string.format("readFileChunk(%s, %d) returns EOF\n", filename, nBytes))

    endI

    return readBuf

end

local function closeFile(filename)

    io.close(readFiles[filename])

    readFiles[filename] = nil

end

function PSUploadAPI.uploadPictureFile(...)

...

    openFile(srcFilename)

    local respBody, respHeaders = LrHttp.post(h.serverUrl .. h.uploadPath, readFileChunk(srcFilename, 10000), postHeaders, 'POST', timeout, fileSize)

    closeFile(srcFilename)

I could verify that readFileChunk() works as expected (from LrHttp.post()), returning chunks of max 10.000 Bytes until EOF, when it returns nil. But for some reason LrHttp.post() is calling the callback function only once.

Questions:

  • Can anybody confirm a size limitation in LrFileUtils.fileRead() somewhere below 2GB?
  • Is anybody using LrHttp.post() with a callback function other than LrFileUtils.fileRead() successfully?

Thanks, Martin

TOPICS
SDK

Views

478

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jan 31, 2017 Jan 31, 2017

The code fragment you posted:

LrHttp.post(h.serverUrl .. h.uploadPath, readFileChunk(srcFilename, 10000),

is passing the result of calling readFileChunk() rather than a callback function.  Thus, it is only getting called once.   I think you'll probably want to do something like:

LrHttp.post(h.serverUrl .. h.uploadPath, function () return readFileChunk(srcFilename, 10000) end,

Votes

Translate

Translate
LEGEND ,
Jan 31, 2017 Jan 31, 2017

Copy link to clipboard

Copied

The code fragment you posted:

LrHttp.post(h.serverUrl .. h.uploadPath, readFileChunk(srcFilename, 10000),

is passing the result of calling readFileChunk() rather than a callback function.  Thus, it is only getting called once.   I think you'll probably want to do something like:

LrHttp.post(h.serverUrl .. h.uploadPath, function () return readFileChunk(srcFilename, 10000) end,

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 01, 2017 Feb 01, 2017

Copy link to clipboard

Copied

Hi John,

thanks for your prompt response, once again. I really appreciate your help!

Stupid me! You 're totally right, I wanted the chunk reader function to be used as callback not its result. The original code was misleading me. I'll check it in the evening, but I'm pretty sure it will work that way!

Thanks, Martin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 01, 2017 Feb 01, 2017

Copy link to clipboard

Copied

When I used to be a developer and then a manager, one of my mottos was, "Two pairs of eyes".

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 01, 2017 Feb 01, 2017

Copy link to clipboard

Copied

LATEST

Jep, sometimes it takes two pairs of eyes!

Works as expected. Using chunks of 10 MBytes seems to be slightly faster than using LrFileUtils.readFile() at least for large video files.

The code is quite straight forward after all:

local postFile = io.open(srcFilename, "rb")

if not postFile then return false end

local respBody, respHeaders = LrHttp.post(h.serverUrl .. h.uploadPath, function () return postFile:read(10000000) end,                                                                       postHeaders, 'POST', timeout, fileSize)

postFile:close()

Thanks again!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines