cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

ThingWorx Navigate is now Windchill Navigate Learn More

Translate the entire conversation x

Efficient way to rename files in ThingWorx FileRepository (maintain numeric order after add/delete)

MA8731174
16-Pearl

Efficient way to rename files in ThingWorx FileRepository (maintain numeric order after add/delete)

 

Hi everyone,

I’m working with a ThingWorx FileRepository where each subfolder contains only 3–4 images (like step images in an Experience).
Whenever I add or delete images, I want to re-sort and rename all files sequentially — e.g.,

 

 
1.png 2.png 3.png 4.png

 

 

so the order always stays clean and consistent.

 


Question:

Given that each folder has only a few files (3–4 images), should I:

  1. Keep this simple in-ThingWorx loop (since performance impact is negligible), or

  2. Use a REST API batch rename approach for better scalability?


Option 1 – In-ThingWorx loop (current working code)

Simple and clear
Calls RenameFile() multiple times (one per file)

 

 
const repoThing = Things[me.getFileRepository()];
for each (var row in existingExperienceStepFiles.rows) {
    var lastSlash = row.path.lastIndexOf("/");
    var dir = row.path.substring(0, lastSlash);
    var newName = (++i) + ".png";
    var newPath = dir + "/" + newName;

    repoThing.RenameFile({ path: row.path, name: newPath });
}

 

 

Option 2 – REST API Batch Rename from Thingworx

Ideal if many files or automation outside ThingWorx
Adds external dependency

 

 


const files = [
  { path: "/Folder/old1.png", newName: "1.png" },
  { path: "/Folder/old2.png", newName: "2.png" }
];

for (const [i, f] of files.entries()) {
  const body = {
    path: f.path,
    name: `/Folder/${f.newName}`
  };

  await fetch("https://<ThingworxServer>/Thingworx/Things/MyFileRepository/Services/RenameFile", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "appKey": "<YourAppKey>"
    },
    body: JSON.stringify(body)
  });
}


My current thought:

Since each folder has at most 3–4 images, I assume the current in-ThingWorx loop approach is fine and has no performance issue.
However, I’d appreciate confirmation or best-practice advice —
Is there a recommended pattern in ThingWorx for renaming small batches of files efficiently?

ACCEPTED SOLUTION

Accepted Solutions
slangley
23-Emerald III
(To:MA8731174)

Hi @MA8731174 

 

For managing the renaming of images in a ThingWorx FileRepository, both approaches you mentioned have their merits, but given your specific scenario of handling only 3–4 images per folder, the in-ThingWorx loop is a practical choice.

 

In-ThingWorx Loop: This method is simple and clear, allowing you to rename files sequentially with minimal overhead. Since the performance impact is negligible with such a small number of files, this approach is efficient for your needs. Your current implementation effectively renames files in a straightforward manner, and it keeps the logic contained within ThingWorx, which can simplify maintenance.

 

REST API Batch Rename: While this method is more scalable and ideal for larger batches or automation scenarios outside of ThingWorx, it introduces additional complexity and external dependencies. For your case, where the number of images is limited, the overhead of setting up and managing API calls may not be justified.

 

In summary, for renaming small batches of files (3–4 images), the in-ThingWorx loop is recommended due to its simplicity and efficiency. If your requirements change in the future and you need to handle larger batches or integrate with external systems, you can consider transitioning to the REST API approach at that time.

 

Regards.

 

--Sharon

View solution in original post

3 REPLIES 3
slangley
23-Emerald III
(To:MA8731174)

Hi @MA8731174 

 

For managing the renaming of images in a ThingWorx FileRepository, both approaches you mentioned have their merits, but given your specific scenario of handling only 3–4 images per folder, the in-ThingWorx loop is a practical choice.

 

In-ThingWorx Loop: This method is simple and clear, allowing you to rename files sequentially with minimal overhead. Since the performance impact is negligible with such a small number of files, this approach is efficient for your needs. Your current implementation effectively renames files in a straightforward manner, and it keeps the logic contained within ThingWorx, which can simplify maintenance.

 

REST API Batch Rename: While this method is more scalable and ideal for larger batches or automation scenarios outside of ThingWorx, it introduces additional complexity and external dependencies. For your case, where the number of images is limited, the overhead of setting up and managing API calls may not be justified.

 

In summary, for renaming small batches of files (3–4 images), the in-ThingWorx loop is recommended due to its simplicity and efficiency. If your requirements change in the future and you need to handle larger batches or integrate with external systems, you can consider transitioning to the REST API approach at that time.

 

Regards.

 

--Sharon

solution looks fine for me as well.

 

Option 1: First look the algorithm looks a little 'scary' with the potential that it might overtwrite other files?

Like e.g. you have 1.png and newImage.png. Then your call renameFiles service. First file in loop might be newImage.png, so you rename it to 1.png. But 1.png already exists? It might fail with "file already exists", but i did not try it.

 

Option 2: You might want to not expose "RenameFile" service of FileRepository directly but add your own wrapper service. Where you could to some permission validations. Exposing "RenameFile" will allow users to rename ANY files in this file repo. But you might only want to be able to rename files in a subdirectory or so (depends on usecase for sure ;))

Hi @nmutter Thank you for your feedback in this case. I have already considered these points which you have mentioned. So First of all i  have one base folder and in that i have all customer folders for each one and there i save photos for each customer in the respected folders. 

 

This service below gives me results in an order so that as you have mentioned in point 1 if i have already 1.png overwriting the file.. so that does not happen and we are safe there.

 

 

const serviceName = "getImageDataOnMashup";
const LOG_PREFIX = me.name + " :: " + serviceName + " :: ";
logger.info(LOG_PREFIX + "Start Service");

let result;
let fileLinks;
let fileRepository = me.getFileRepository();
let entry;
let imageRepositoryPath;

try {
 entry = me.getExperienceStepByKey({ selectedEntryPrimayKey: selectedEntryPrimayKey });   
 imageRepositoryPath = entry.rows[0].imagePath;
 fileLinks = Things[fileRepository].GetFileListingWithLinks({path:imageRepositoryPath});
    let query = {
        "filters": {
            "type": "NOTLIKE",
            "fieldName": "path",
            "value": "*pdf"
        }
    };

    fileLinks = Resources["InfoTableFunctions"].Query({t: fileLinks, query: query});
    fileLinks = Resources["InfoTableFunctions"].Sort({
        sortColumn: "lastModifiedDate" /* STRING */,
        t: fileLinks /* INFOTABLE */,
        ascending: true /* BOOLEAN */
    });
} catch (e) {

fileLinks = DataShapes["myDataShape.DS"].CreateValues();
    
}

 result = fileLinks;

logger.info(LOG_PREFIX + "End Service");

 

 

secondly here is the below service which actually does the job for me when i upload the photo in the repository in each step..

 

 

const serviceName = "assignStepPhotosOrder";
const LOG_PREFIX = me.name + " :: " + serviceName + " :: ";
logger.info(LOG_PREFIX + "Start Service");

const fileRepository = me.getFileRepository();
let existingExperienceStepFiles = me.getImageDataOnMashup({selectedEntryPrimayKey:selectedEntryPrimayKey});


existingExperienceStepFiles.rows.toArray().forEach((row, index) => {
   
    const lastSlashIndex = row.path.lastIndexOf("/"); // 
/base folder/customer//STEP_1762498888080/Bild.png 
    const directoryPath = row.path.substring(0, lastSlashIndex); 
// base folder/customer/STEP_1762498888080
     
    const newFileName = String(index + 1 +".png"); // index starts with 0 so i am adding 1 here.
    const newFullPath = directoryPath + "/" + newFileName;

    Things[fileRepository].RenameFile({
        path: row.path,
        name: newFullPath 
// base folder/customer/STEP_1762498888080/1.png 
    });
});

let result = existingExperienceStepFiles;

logger.info(LOG_PREFIX + "End Service");

 

 

 

Announcements


Top Tags