I'm trying to build a file based integration where files are dumped in one of the subdirectories of a main directory for processing. I need to get the name of the sub-directory to know which client the file is for. So if I have:
/uploads/foo/bar.txt
I need to process that file and know that it's for client "foo". I'm not sure how to get that part and set it as a header for the processor that processes the bar.txt file. I've got it picking up files and processing, now I need to add in this piece.
Anyone have ideas for me?
You can get most of this information in the header of the exchange. In your situation as you are consuming the file the following items are avlable:
CamelFileName: Name of the consumed file as a relative file path with
offset from the starting directory configured on the endpoint.
CamelFileNameOnly: Only the file name (the name with no leading
paths).
CamelFileAbsolute: A boolean option specifying whether the consumed
file denotes an absolute path or not. Should normally be false for
relative paths. Absolute paths should normally not be used but we
added to the move option to allow moving files to absolute paths. But
can be used elsewhere as well.
CamelFileAbsolutePath: The absolute path to the file. For relative
files this path holds the relative path instead.
CamelFilePath: The file path. For relative files this is the starting directory + the relative filename. For absolute files this is the absolute path.
CamelFileRelativePath: The relative path.
CamelFileParent: The parent path.
CamelFileLength: A long value containing the file size.
CamelFileLastModified: A Date value containing the last modified
timestamp of the file.
You can query these headers for the information you are looking for using the following example as guidelines:
<log message ="${header.CamelFileAbsolutePath}"/>
See the file component documents at the Camel website for more details.
Related
I have created a batch script that requires the location of 2 files to be passed into it. I would like it to work regardless of whether the user gives the full file path or relative file path of the files to be read in.
I've tried the following
set Var1=%~dp0%1
set Var2=%~dp0%2
which only works if relative file path is given. Without %~dp0obviously only works if full path is given.
Is there a way for either the full or relative path to be given and for my batch file to work.
Thanks
source_dir Have files like: ABC_02022018_162301.CSV, ABC_02022018_231801.CSV, controlFile
<route id="Test">
<from uri="file:source_dir?include=ABC_.*\.CSV&doneFileName=controlFile&delete=true&readLock=changed&readLockTimeout=20000&readLockCheckInterval=5000&eadLockMinLength=0"/>
<log message="${file:name}"/>
**destination directory **
</route>
I am looking here is, route has to check controlFile for every main file. If any main file doesn't have control file, main file shouldn't move from source folder.
In my above code, camel only once checking for control file existence in source folder and moving all the files to destination folder. Can anyone please help on this?
According to the Camel docs (section 'Using 'done' Files'), in order to have one doneFile per main file you need to specify dynamic doneFile names:
it is more common to have one done file per target file. This means
there is a 1:1 correlation. To do this you must use dynamic
placeholders in the doneFileName option. Currently Camel supports the
following two dynamic tokens: file:name and file:name.noext which must
be enclosed in ${}
if you don't, then Camel will consume all files and then delete the doneFile unless noop=true
Short answer: if you define doneFileName dynamically like this "doneFileName=${file:name.noext}.trig" then each file you want to transfer must have a copy with .trig extension.
If you define doneFileName statically like "doneFileName=files.trig" then every file will be moved when files.trig appears.
So you have to think of a unique doneFileName for each file instead of "controlFile" and set it dynamically. Easiest way is to use the actual fileName and add some extension.
Examples:
Imagine this files: file1.txt, file2.txt
and this route from:
from("ftp://admin#localhost/from?password=admin"
+ "&fileName=${file:name}"
+ "&doneFileName=${file:name.noext}.done")
In this case file1.txt will be moved only if file1.done is also present in the same folder. file2.txt will be moved only if file2.done is also present in the same folder.
Now imagine this route:
from("ftp://admin#localhost/from?password=admin"
+ "&fileName=${file:name}"
+ "&doneFileName=controlFile");
In this case both files file1.txt and file2.txt will be moved when files.done file is present in the same folder.
I'm working with C right now. And there's a problem. I don't know how to save a FILE in custom place. When I run *.exe file, it saves them where code is placed. So how to make it save FILEs where I want it to be?(I can input a path)
a FILE is actually a long type that addresses a path on your computer.
Whether you use linux, windows, etc, the common thing about the paths is the idea that there are relative paths or absolute paths.
From what I've understood you probably did use the relative path, and I can guess you didn't specified a path at all, but only the file name.
Notice that a file's name alone is placed relatively to the path of the program you are running.
To fix your problem you might want to give an absolute path (such as "/home/user/" on linux or "C:\Users\user" on windows [pay attention for the escaping backslash]).
You can do it by something like this:
FILE *output = fopen("/home/user/output.txt", "w");
(where "w" means writing permissions to the file at the given path).
Hope this answers your question.
As per https://camel.apache.org/file2.html, file component cannot be configured with dynamic input/output folder locations?
Is there any workaround/alternative for the same?
Thanks.
Regards
Senthil Kumar Sekar
For the file consumer
You can use a customer filter as dynamic selection of which directories/files to pickup. But the starting directory is configured once (hardcoded).
For that to change you would need to stop the route, and change the directory, and start the route again - if you want to attempt that direction.
For the file producer
The file name is fully dynamic you can just set a name as the file header you want. See documentation for details.
You can use the header CamelFileName also to dynamically set a directory. Slashes will be turned into directories.
Example: CamelFileName = "directory/dyn_subdirectory_n/myfilename.txt" will be placed into the directory "dyn_subdirectory_n" located in "directory". The filename will be "myfilename.txt".
I have a C console app where I need to output the absolute path to a file given a (possibly) relative path. What is the best way to do this in C in a Windows environment?
I think you are looking for _fullpath().
GetFullPathName should help you on Windows.
GetFullPathName merges the name of the current drive and directory
with a specified file name to determine the full path and file name of
a specified file.