cat somefile.nc | ncks --jsn errors with: ncks: ERROR received 0 filenames; need at least one
using Nim to call ncks works fine this way
let fn = "somefile.nc"
let tenminfile = execProcess("ncks", args = ["--jsn", fn], options={poUsePath})
this works fine for what I do now, but for a small project I have to downlod thousands of files and I'd like to "bypass" the file writing to disk. Do it all in memory. So I tried:
let fn = "somefile.nc"
let fin = readFile(fn) #imagine as body(stream?) from httpclient download.
var tenminfile=""
let p = startProcess("ncks", args = ["--jsn"], options={poUsePath})
inputStream(p).writeData(addr(fin), sizeof(fin))
for line in p.lines:
tenminfile &= line
p.close
That results in the same ERROR received 0 filenames Mayby try the filehandle? Adding:
let ih = inputHandle(p)
echo getFileInfo(ih)
(on windows) results in: Error: unhandled exception: The handle is invalid. Additional info: 212 [OSError]
Is there a way to "fake" a file? Make the dowloaded data look like a file? Create some virtual file, that works for Win11 and FreeBSD? (not using a RAMdisk)
You can probably use process substitution <(). That should work in FreeBsd and WSL and Linux:
$ ./some-exe-that-expects-filename <(echo "raw contents")
Small demo:
# test.nim
import std/cmdline;
proc main =
let fd = paramStr(1)
let vfile = fd.open()
defer:
vfile.close()
echo "file descriptor: " & fd
echo "contents: " & vfile.readAll()
main()
$ nim c test.nim
$ ./test <(curl google.com)
file descriptor: /proc/self/fd/11
contents: <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
For Windows see this answer on StackOverflow about Named Pipes
a followup. Windows' named pipes do not seem to be the thing to use in this case. It seems that the consumer on the other side of the pipe also needs some fitting machinery. Something that is seldom available. The alternative route seems to be virtual temp files, that under the right circumstances are not written to disc. A bit like the in memory tmpfs
Two things that are a bit shaky fro me. FILE_SHARE_DELETE + FILE_SHARE_READ seems to work as reading and deleting works, but is was more of a guess to + them together. The other one is the FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, when I do that the whole thing does not work anymore.
import winim
#https://learn.microsoft.com/en-us/archive/blogs/larryosterman/its-only-temporary
#https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
let tempFileName = "ncfile.txt"
let t: cstring = "test text for nc file"
var bytesWritten: DWORD
var ncfile = CreateFileA(
tempFileName,
GENERIC_WRITE,
FILE_SHARE_DELETE + FILE_SHARE_READ, #read and delete while the file handle exists.
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY, # or FILE_FLAG_DELETE_ON_CLOSE #0x00000100'i32 | 0x04000000'i32
0
)
WriteFile(ncfile, t, (DWORD) t.len, addr(bytesWritten) , NULL)
echo bytesWritten
let tenminfile = execProcess("cat", args = [tempFileName], options={poUsePath})
DeleteFileA(tempFileName)
CloseHandle(ncfile)
echo tenminfile
on the other side of the pipe also needs some fitting machinery
As far as I remember, it just needs to open the pipe with the appropriate call (CreateFile). Basic Windows tools like the type command should have no problem reading from the pipe.
The problem I had last time I tried to use Named Pipes is that I couldn't make them persistent and had to close them and recreate after each write operation (the part my program controlled was the server/read-side that was written to, substituting a UNIX socket/FIFO for IPC). That's ugly but works and that was all I cared at the moment.
As far as I remember, it just needs to open the pipe with the appropriate call (CreateFile). Basic Windows tools like the type command should have no problem reading from the pipe.
the main problem is that the ncks tool expects a file. it results in: Get-Content: All pipe instances are busy. : '\\.\pipe\ncpipe'