diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-84184-ShowColumnsSelectionInFilelist.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-84184-ShowColumnsSelectionInFilelist.rst
new file mode 100644
index 0000000000000000000000000000000000000000..451c09fa4c82e152a45148878adff0c0826d1d6d
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-84184-ShowColumnsSelectionInFilelist.rst
@@ -0,0 +1,38 @@
+.. include:: ../../Includes.txt
+
+====================================================
+Feature: #84184 - Show columns selection in filelist
+====================================================
+
+See :issue:`84184`
+
+Description
+===========
+
+The column selector, introduced in :issue:`94218` and improved
+in :issue:`94474` is now also available in the filelist module.
+
+As already known from the recordlist, it can be used to manage the fields,
+displayed for each file / folder, while containing convenience actions,
+such as "filter", "check all / none" and "toggle selection".
+
+The fields to be selected are a combination of special fields, such as
+`references` or `read/write` permissions, the corresponding `sys_file`
+record fields, as well as all available `sys_file_metadata` fields.
+
+Administrators can manage whether the column selection is available
+for their users with a new user TSconfig option:
+
+.. code-block:: typoscript
+
+   # disable the column selector
+   file_list.displayColumnSelector = 0
+
+
+Impact
+======
+
+It's now possible to manage the displayed fields for files / folders
+in the filelist module, using the columns selection component.
+
+.. index:: Backend
diff --git a/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf b/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
index 86d0b98aa7b31443d060f592ed0c263f907a5602..686008f851ff00727bb61f00de5497be84f4a926 100644
--- a/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
+++ b/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
@@ -134,13 +134,13 @@ Do you want to continue WITHOUT saving?</source>
 				<source>Parent page ID</source>
 			</trans-unit>
 			<trans-unit id="labels.tstamp" resname="labels.tstamp">
-				<source>Last changed</source>
+				<source>Last modified</source>
 			</trans-unit>
 			<trans-unit id="labels.crdate" resname="labels.crdate">
 				<source>Creation date</source>
 			</trans-unit>
 			<trans-unit id="labels.cruser_id" resname="labels.cruser_id">
-				<source>Creator</source>
+				<source>Created by</source>
 			</trans-unit>
 			<trans-unit id="labels.sorting" resname="labels.sorting">
 				<source>Sorting</source>
diff --git a/typo3/sysext/filelist/Classes/Controller/FileListController.php b/typo3/sysext/filelist/Classes/Controller/FileListController.php
index a9c24cacbe54f2d111ff08f4b2af3673e1ad2adc..93520758bf26cb7986e28e9b921a2e4e8f7415dd 100644
--- a/typo3/sysext/filelist/Classes/Controller/FileListController.php
+++ b/typo3/sysext/filelist/Classes/Controller/FileListController.php
@@ -270,6 +270,7 @@ class FileListController implements LoggerAwareInterface
         $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileDelete');
         $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
         $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/MultiRecordSelection');
+        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/ColumnSelectorButton');
         $this->pageRenderer->addInlineLanguageLabelFile(
             'EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf',
             'buttons'
@@ -370,6 +371,7 @@ class FileListController implements LoggerAwareInterface
             (string)($this->MOD_SETTINGS['sort'] ?? ''),
             (bool)($this->MOD_SETTINGS['reverse'] ?? false)
         );
+        $this->filelist->setColumnsToRender($this->getBackendUser()->getModuleData('list/displayFields')['_FILE'] ?? []);
     }
 
     protected function generateFileList(): void
@@ -385,6 +387,7 @@ class FileListController implements LoggerAwareInterface
         if ($this->folderObject->getStorage()->isBrowsable()) {
             $this->view->assignMultiple([
                 'listHtml' => $this->filelist->getTable($searchDemand),
+                'listUrl' => $this->filelist->listURL(),
                 'totalItems' => $this->filelist->totalItems
             ]);
             if ($this->filelist->totalItems === 0 && $searchDemand !== null) {
@@ -404,6 +407,20 @@ class FileListController implements LoggerAwareInterface
                     'returnUrl' => $this->filelist->listURL()
                 ])
             ]);
+
+            // Add column selector information if enabled
+            if ($this->getBackendUser()->getTSConfig()['options.']['file_list.']['displayColumnSelector'] ?? true) {
+                $this->view->assign('columnSelector', [
+                    'url' => $this->uriBuilder->buildUriFromRoute(
+                        'ajax_record_show_columns_selector',
+                        ['id' => $this->id, 'table' => '_FILE']
+                    ),
+                    'title' => sprintf(
+                        $lang->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:showColumnsSelection'),
+                        $lang->sL($GLOBALS['TCA']['sys_file']['ctrl']['title'] ?? ''),
+                    ),
+                ]);
+            }
         } else {
             $this->addFlashMessage(
                 $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:storageNotBrowsableMessage'),
diff --git a/typo3/sysext/filelist/Classes/FileList.php b/typo3/sysext/filelist/Classes/FileList.php
index 55df91ec3ebcc9fc3347cf6d3cd2d15202722008..459fcf7aff35ca69541a7e7f5feea1e08f162ff4 100644
--- a/typo3/sysext/filelist/Classes/FileList.php
+++ b/typo3/sysext/filelist/Classes/FileList.php
@@ -16,6 +16,7 @@
 namespace TYPO3\CMS\Filelist;
 
 use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Backend\Avatar\Avatar;
 use TYPO3\CMS\Backend\Clipboard\Clipboard;
 use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
@@ -37,6 +38,7 @@ use TYPO3\CMS\Core\Resource\ProcessedFile;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Resource\ResourceInterface;
 use TYPO3\CMS\Core\Resource\Search\FileSearchDemand;
+use TYPO3\CMS\Core\Resource\StorageRepository;
 use TYPO3\CMS\Core\Resource\Utility\ListUtility;
 use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -137,7 +139,7 @@ class FileList
         '_CONTROL_' => 'col-control',
         '_SELECTOR_' => 'col-selector',
         'icon' => 'col-icon',
-        'file' => 'col-title col-responsive',
+        'name' => 'col-title col-responsive',
         '_LOCALIZATION_' => 'col-localizationa',
     ];
 
@@ -180,6 +182,12 @@ class FileList
 
     protected array $selectedElements = [];
 
+    /**
+     * A runtime first-level cache to avoid unneeded calls to BackendUtility::getRecord()
+     * @var array
+     */
+    protected array $backendUserCache = [];
+
     public function __construct(?ServerRequestInterface $request = null)
     {
         // Setting the maximum length of the filenames to the user's settings or minimum 30 (= $this->fixedL)
@@ -217,10 +225,15 @@ class FileList
         $this->sortRev = $sortRev;
         $this->firstElementNumber = $pointer;
         $this->fieldArray = [
-            '_SELECTOR_', 'icon', 'file', '_LOCALIZATION_', '_CONTROL_', 'fileext', 'tstamp', 'size', 'rw', '_REF_'
+            '_SELECTOR_', 'icon', 'name', '_LOCALIZATION_', '_CONTROL_', 'record_type', 'size', 'rw', '_REF_'
         ];
     }
 
+    public function setColumnsToRender(array $additionalFields = []): void
+    {
+        $this->fieldArray = array_unique(array_merge($this->fieldArray, $additionalFields));
+    }
+
     /**
      * Returns a table with directories and files listed.
      *
@@ -327,16 +340,16 @@ class FileList
 
         // Header line is drawn
         $theData = [];
-        foreach ($this->fieldArray as $v) {
-            if ($v === '_SELECTOR_') {
-                $theData[$v] = $this->renderCheckboxActions();
-            } elseif ($v === '_REF_') {
-                $theData[$v] = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels._REF_'));
-            } elseif ($v === '_PATH_') {
-                $theData[$v] = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels._PATH_'));
-            } elseif ($v !== 'icon') {
-                // Normal row - except "icon", which does not need a table header col
-                $theData[$v]  = $this->linkWrapSort($v);
+        foreach ($this->fieldArray as $fieldName) {
+            if ($fieldName === '_SELECTOR_') {
+                $theData[$fieldName] = $this->renderCheckboxActions();
+            } elseif ($specialLabel = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.' . $fieldName)) {
+                $theData[$fieldName] = htmlspecialchars($specialLabel);
+            } elseif ($customLabel = $this->getLanguageService()->getLL('c_' . $fieldName)) {
+                $theData[$fieldName] = $this->linkWrapSort($fieldName, $customLabel);
+            } elseif ($fieldName !== 'icon') {
+                // Normal database field
+                $theData[$fieldName] = $this->linkWrapSort($fieldName);
             }
         }
 
@@ -409,7 +422,7 @@ class FileList
                 // 	Reverse
                 $theData = [];
                 $href = $this->listURL(['pointer' => ($currentItemCount - $this->iLimit)]);
-                $theData['file'] = '<a href="' . htmlspecialchars($href) . '">' . $this->iconFactory->getIcon(
+                $theData['name'] = '<a href="' . htmlspecialchars($href) . '">' . $this->iconFactory->getIcon(
                     'actions-move-up',
                     Icon::SIZE_SMALL
                 )->render() . ' <i>[' . (max(0, $currentItemCount - $this->iLimit) + 1) . ' - ' . $currentItemCount . ']</i></a>';
@@ -421,7 +434,7 @@ class FileList
             // 	Forward
             $theData = [];
             $href = $this->listURL(['pointer' => $currentItemCount]);
-            $theData['file'] = '<a href="' . htmlspecialchars($href) . '">' . $this->iconFactory->getIcon(
+            $theData['name'] = '<a href="' . htmlspecialchars($href) . '">' . $this->iconFactory->getIcon(
                 'actions-move-down',
                 Icon::SIZE_SMALL
             )->render() . ' <i>[' . ($currentItemCount + 1) . ' - ' . $this->totalItems . ']</i></a>';
@@ -494,7 +507,7 @@ class FileList
                     $theData[$field] = '';
                 }
                 $theData['icon'] = $theIcon;
-                $theData['file'] = $displayName;
+                $theData['name'] = $displayName;
             } else {
                 foreach ($this->fieldArray as $field) {
                     switch ($field) {
@@ -509,17 +522,13 @@ class FileList
                         case 'rw':
                             $theData[$field] = '<strong class="text-danger">' . htmlspecialchars($this->getLanguageService()->getLL('read')) . '</strong>' . (!$isWritable ? '' : '<strong class="text-danger">' . htmlspecialchars($this->getLanguageService()->getLL('write')) . '</strong>');
                             break;
-                        case 'fileext':
+                        case 'record_type':
                             $theData[$field] = htmlspecialchars($this->getLanguageService()->getLL('folder'));
                             break;
-                        case 'tstamp':
-                            $tstamp = $folderObject->getModificationTime();
-                            $theData[$field] = $tstamp ? BackendUtility::date($tstamp) : '-';
-                            break;
                         case 'icon':
                             $theData[$field] = (string)BackendUtility::wrapClickMenuOnIcon($theIcon, 'sys_file', $folderObject->getCombinedIdentifier());
                             break;
-                        case 'file':
+                        case 'name':
                             $theData[$field] = $this->linkWrapDir($displayName, $folderObject);
                             break;
                         case '_CONTROL_':
@@ -666,11 +675,8 @@ class FileList
                     case 'rw':
                         $theData[$field] = '' . (!$fileObject->checkActionPermission('read') ? ' ' : '<strong class="text-danger">' . htmlspecialchars($this->getLanguageService()->getLL('read')) . '</strong>') . (!$fileObject->checkActionPermission('write') ? '' : '<strong class="text-danger">' . htmlspecialchars($this->getLanguageService()->getLL('write')) . '</strong>');
                         break;
-                    case 'fileext':
-                        $theData[$field] = htmlspecialchars(strtoupper($ext));
-                        break;
-                    case 'tstamp':
-                        $theData[$field] = BackendUtility::date($fileObject->getModificationTime());
+                    case 'record_type':
+                        $theData[$field] = htmlspecialchars($this->getLanguageService()->getLL('file') . ($ext ? ' (' . strtoupper($ext) . ')' : ''));
                         break;
                     case '_CONTROL_':
                         $theData[$field] = $this->makeEdit($fileObject);
@@ -733,7 +739,7 @@ class FileList
                     case 'icon':
                         $theData[$field] = (string)BackendUtility::wrapClickMenuOnIcon($this->getFileOrFolderIcon($fileName, $fileObject), 'sys_file', $fileObject->getCombinedIdentifier());
                         break;
-                    case 'file':
+                    case 'name':
                         // Edit metadata of file
                         $theData[$field] = $this->linkWrapFile(htmlspecialchars($fileName), $fileObject);
 
@@ -759,7 +765,33 @@ class FileList
                     default:
                         $theData[$field] = '';
                         if ($fileObject->hasProperty($field)) {
-                            $theData[$field] = htmlspecialchars(GeneralUtility::fixed_lgd_cs($fileObject->getProperty($field), $this->fixedL));
+                            $concreteTableName = $this->getConcreteTableName($field);
+                            if ($field === ($GLOBALS['TCA'][$concreteTableName]['ctrl']['cruser_id'] ?? '')) {
+                                // Handle cruser_id by adding the avatar along with the username
+                                $theData[$field] = $this->getBackendUserInformation((int)$fileObject->getProperty($field));
+                            } elseif ($field === ($GLOBALS['TCA'][$concreteTableName]['ctrl']['crdate'] ?? '')) {
+                                // This special case is needed since crdate is defined as "passthrough"
+                                // in sys_file_metadata due to the file search API and will therefore not
+                                // be processed by getProcessedValue.
+                                $theData[$field] = htmlspecialchars(BackendUtility::datetime((int)$fileObject->getProperty($field)));
+                            } elseif ($field === 'storage') {
+                                // Fetch storage name of the current file
+                                $storage = GeneralUtility::makeInstance(StorageRepository::class)->findByUid((int)$fileObject->getProperty($field));
+                                if ($storage !== null) {
+                                    $theData[$field] = htmlspecialchars($storage->getName());
+                                }
+                            } else {
+                                $theData[$field] = htmlspecialchars(
+                                    BackendUtility::getProcessedValueExtra(
+                                        $this->getConcreteTableName($field),
+                                        $field,
+                                        $fileObject->getProperty($field),
+                                        $this->fixedL,
+                                        $fileObject->getMetaData()->offsetGet('uid'),
+                                        true
+                                    )
+                                );
+                            }
                         }
                 }
             }
@@ -801,17 +833,33 @@ class FileList
     }
 
     /**
-     * Wraps the directory-titles ($code) in a link to filelist/Modules/Filelist/index.php (id=$path) and sorting commands...
+     * Wraps a field label for the header row into a link to the filelist with sorting commands
      *
-     * @param string $col Sorting column
-     * @return string HTML
+     * @param string $fieldName The field to sort
+     * @param string $label The label to be wrapped - will be determined if not given
+     * @return string The constructed link - HTML
      */
-    public function linkWrapSort($col)
+    public function linkWrapSort(string $fieldName, string $label = ''): string
     {
-        $code = htmlspecialchars($this->getLanguageService()->getLL('c_' . $col));
-        $params = ['SET' => ['sort' => $col], 'pointer' => 0];
+        // Determine label if not given
+        if ($label === '') {
+            $lang = $this->getLanguageService();
+            $concreteTableName = $this->getConcreteTableName($fieldName);
+            $label = $lang->sL(BackendUtility::getItemLabel($concreteTableName, $fieldName) ?? '');
+            if ($label !== '') {
+                // In case global TSconfig exists we have to check if the label is overridden there
+                $tsConfig = BackendUtility::getPagesTSconfig(0);
+                if (!empty($tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label.'][$lang->lang])) {
+                    $label = $tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label.'][$lang->lang];
+                } elseif (!empty($tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label'])) {
+                    $label = $tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label'];
+                }
+            }
+        }
+
+        $params = ['SET' => ['sort' => $fieldName], 'pointer' => 0];
 
-        if ($this->sort === $col) {
+        if ($this->sort === $fieldName) {
             // Check reverse sorting
             $params['SET']['reverse'] = ($this->sortRev ? '0' : '1');
             $sortArrow = $this->iconFactory->getIcon('status-status-sorting-' . ($this->sortRev ? 'desc' : 'asc'), Icon::SIZE_SMALL)->render();
@@ -820,7 +868,8 @@ class FileList
             $sortArrow = '';
         }
         $href = $this->listURL($params);
-        return '<a href="' . htmlspecialchars($href) . '">' . $code . ' ' . $sortArrow . '</a>';
+
+        return '<a href="' . htmlspecialchars($href) . '">' . htmlspecialchars($label) . ' ' . $sortArrow . '</a>';
     }
 
     /**
@@ -1273,6 +1322,38 @@ class FileList
             </div>';
     }
 
+    /**
+     * Helper method around fetching a "cruser_id" information for a record, with a cache, so the same information
+     * does not have to be processed for the same user over and over again.
+     */
+    protected function getBackendUserInformation(int $backendUserId): string
+    {
+        if (!isset($this->backendUserCache[$backendUserId])) {
+            $beUserRecord = BackendUtility::getRecord('be_users', $backendUserId);
+            if (is_array($beUserRecord)) {
+                $avatar = GeneralUtility::makeInstance(Avatar::class);
+                $label = htmlspecialchars(BackendUtility::getRecordTitle('be_users', $beUserRecord));
+                $content = $avatar->render($beUserRecord) . '<strong>' . $label . '</strong>';
+            } else {
+                $content = '<strong>&ndash;</strong>';
+            }
+            $this->backendUserCache[$backendUserId] = $content;
+        }
+        return $this->backendUserCache[$backendUserId];
+    }
+
+    /**
+     * Determine the concrete table name by checking if
+     * the field exists, while sys_file takes precedence.
+     *
+     * @param string $fieldName
+     * @return string
+     */
+    protected function getConcreteTableName(string $fieldName): string
+    {
+        return ($GLOBALS['TCA']['sys_file']['columns'][$fieldName] ?? false) ? 'sys_file' : 'sys_file_metadata';
+    }
+
     /**
      * Returns an instance of LanguageService
      *
diff --git a/typo3/sysext/filelist/Resources/Private/Language/locallang_mod_file_list.xlf b/typo3/sysext/filelist/Resources/Private/Language/locallang_mod_file_list.xlf
index 9cfbc2b88566e28450337bf0c75d585f2993a1a7..75973249fb62b212137c28c6418c22d37e4ee2c9 100644
--- a/typo3/sysext/filelist/Resources/Private/Language/locallang_mod_file_list.xlf
+++ b/typo3/sysext/filelist/Resources/Private/Language/locallang_mod_file_list.xlf
@@ -27,21 +27,15 @@
 			<trans-unit id="displayThumbs" resname="displayThumbs">
 				<source>Display thumbnails</source>
 			</trans-unit>
-			<trans-unit id="c_file" resname="c_file">
-				<source>File Name</source>
-			</trans-unit>
-			<trans-unit id="c_filepath" resname="c_filepath">
-				<source>File Path</source>
+			<trans-unit id="c_name" resname="c_name">
+				<source>Name</source>
 			</trans-unit>
 			<trans-unit id="c_size" resname="c_size">
 				<source>Size</source>
 			</trans-unit>
-			<trans-unit id="c_fileext" resname="c_fileext">
+			<trans-unit id="c_record_type" resname="c_record_type">
 				<source>Type</source>
 			</trans-unit>
-			<trans-unit id="c_tstamp" resname="c_tstamp">
-				<source>Last Modified</source>
-			</trans-unit>
 			<trans-unit id="c_rw" resname="c_rw">
 				<source>RW</source>
 			</trans-unit>
diff --git a/typo3/sysext/filelist/Resources/Private/Templates/File/List.html b/typo3/sysext/filelist/Resources/Private/Templates/File/List.html
index 42246ec6dc709ac0384464be64e321bcaf5b40b2..74653e46b7552e76df652690f33ed2891a508065 100644
--- a/typo3/sysext/filelist/Resources/Private/Templates/File/List.html
+++ b/typo3/sysext/filelist/Resources/Private/Templates/File/List.html
@@ -76,14 +76,38 @@
                     </div>
                 </f:if>
             </div>
-            <f:if condition="{listHtml} && {displayThumbs.enabled}">
+            <f:if condition="{listHtml}">
                 <div class="col-auto">
-                    <div class="form-check form-switch">
-                        {displayThumbs.html -> f:format.raw()}
-                        <label for="checkDisplayThumbs" class="form-check-label">
-                            {displayThumbs.label}
-                        </label>
-                    </div>
+                    <f:if condition="{columnSelector} || {displayThumbs.enabled}">
+                        <div class="row row-cols-auto align-items-center gx-3">
+                            <f:if condition="{columnSelector}">
+                                <div class="col">
+                                    <typo3-recordlist-column-selector-button
+                                        url="{columnSelector.url}"
+                                        target="{listUrl}"
+                                        title="{columnSelector.title}"
+                                        ok="{f:translate(key: 'LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:updateColumnView')}"
+                                        close="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel')}"
+                                        error="{f:translate(key: 'LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:updateColumnView.error')}">
+                                        <button type="button" class="btn btn-default btn-sm" title="{columnSelector.title}">
+                                            <core:icon identifier="actions-options" size="small" />
+                                            <f:translate key="LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:showColumns" />
+                                        </button>
+                                    </typo3-recordlist-column-selector-button>
+                                </div>
+                            </f:if>
+                            <f:if condition="{displayThumbs.enabled}">
+                                <div class="col">
+                                    <div class="form-check form-switch mb-0">
+                                        {displayThumbs.html -> f:format.raw()}
+                                        <label for="checkDisplayThumbs" class="form-check-label">
+                                            {displayThumbs.label}
+                                        </label>
+                                    </div>
+                                </div>
+                            </f:if>
+                        </div>
+                    </f:if>
                 </div>
             </f:if>
         </div>
diff --git a/typo3/sysext/recordlist/Classes/Controller/ColumnSelectorController.php b/typo3/sysext/recordlist/Classes/Controller/ColumnSelectorController.php
index 6ba7ccd5703d7e8af1231ffdcab5ab64a069bb32..33dbbb678bd8ad36d277fe96cb0ff92f562f05d3 100644
--- a/typo3/sysext/recordlist/Classes/Controller/ColumnSelectorController.php
+++ b/typo3/sysext/recordlist/Classes/Controller/ColumnSelectorController.php
@@ -36,6 +36,18 @@ use TYPO3Fluid\Fluid\View\ViewInterface;
 class ColumnSelectorController
 {
     private const PSEUDO_FIELDS = ['_REF_', '_PATH_'];
+    private const EXCLUDE_FILE_FIELDS = [
+        'pid', // Not relevant as all records are on pid=0
+        'identifier', // Handled manually in listing
+        'name', // Handled manually in listing
+        'metadata', // The reference to the meta data is not relevant
+        'file', // The reference to the file is not relevant
+        'sys_language_uid', // Not relevant in listing since only defualt is displayed
+        'l10n_parent', // Not relevant in listing
+        't3ver_state', // Not relevant in listing
+        't3ver_wsid', // Not relevant in listing
+        't3ver_oid' // Not relevant in listing
+    ];
 
     protected ResponseFactoryInterface $responseFactory;
 
@@ -56,7 +68,7 @@ class ColumnSelectorController
         $table = (string)($parsedBody['table'] ?? '');
         $selectedColumns = $parsedBody['selectedColumns'] ?? [];
 
-        if ($table === '' || !is_array($selectedColumns) || $selectedColumns === []) {
+        if ($table === '' || !is_array($selectedColumns)) {
             return $this->jsonResponse([
                 'success' => false,
                 'message' => htmlspecialchars(
@@ -115,29 +127,42 @@ class ColumnSelectorController
         // Current fields selection
         $displayFields = $this->getBackendUserAuthentication()->getModuleData('list/displayFields')[$table] ?? [];
 
-        // Request fields from table and add pseudo fields
-        $fields = array_merge(
-            GeneralUtility::makeInstance(DatabaseRecordList::class)->makeFieldList($table, false, true),
-            self::PSEUDO_FIELDS
-        );
+        if ($table === '_FILE') {
+            // Special handling for _FILE (merging sys_file and sys_file_metadata together)
+            $fields = $this->getFileFields();
+        } else {
+            // Request fields from table and add pseudo fields
+            $fields = array_merge(
+                GeneralUtility::makeInstance(DatabaseRecordList::class)->makeFieldList($table, false, true),
+                self::PSEUDO_FIELDS
+            );
+        }
 
         $columns = $specialColumns = $disabledColumns = [];
         foreach ($fields as $fieldName) {
+            $concreteTableName = $table;
+
+            // In case we deal with _FILE, the field name is prefixed with the
+            // concrete table name, which is either sys_file or sys_file_metadata.
+            if ($table === '_FILE') {
+                [$concreteTableName, $fieldName] = explode('|', $fieldName);
+            }
+
             // Hide field if disabled
-            if ($tsConfig['TCEFORM.'][$table . '.'][$fieldName . '.']['disabled'] ?? false) {
+            if ($tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['disabled'] ?? false) {
                 continue;
             }
 
             // Determine if the column should be disabled (Meaning it is always selected and can not be turned off)
-            $isDisabled = $fieldName === ($GLOBALS['TCA'][$table]['ctrl']['label'] ?? false);
+            $isDisabled = $fieldName === ($GLOBALS['TCA'][$concreteTableName]['ctrl']['label'] ?? false);
 
             // Determine field label
-            $label = BackendUtility::getItemLabel($table, $fieldName);
+            $label = BackendUtility::getItemLabel($concreteTableName, $fieldName);
             if ($label) {
-                if (!empty($tsConfig['TCEFORM.'][$table . '.'][$fieldName . '.']['label.'][$this->getLanguageService()->lang])) {
-                    $label = $tsConfig['TCEFORM.'][$table . '.'][$fieldName . '.']['label.'][$this->getLanguageService()->lang];
-                } elseif (!empty($tsConfig['TCEFORM.'][$table . '.'][$fieldName . '.']['label'])) {
-                    $label = $tsConfig['TCEFORM.'][$table . '.'][$fieldName . '.']['label'];
+                if (!empty($tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label.'][$this->getLanguageService()->lang])) {
+                    $label = $tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label.'][$this->getLanguageService()->lang];
+                } elseif (!empty($tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label'])) {
+                    $label = $tsConfig['TCEFORM.'][$concreteTableName . '.'][$fieldName . '.']['label'];
                 }
             } elseif ($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.' . $fieldName)) {
                 $label = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.' . $fieldName;
@@ -172,6 +197,36 @@ class ColumnSelectorController
         return array_merge($disabledColumns, $columns, $specialColumns);
     }
 
+    /**
+     * Get file related fields by merging sys_file and sys_file_metadata together
+     * and adding the corresponding table as prefix (needed for labels processing).
+     *
+     * @return array
+     */
+    protected function getFileFields(): array
+    {
+        // Get all sys_file fields expect excluded ones
+        $fileFields = array_filter(
+            GeneralUtility::makeInstance(DatabaseRecordList::class)->makeFieldList('sys_file', false, true),
+            static fn (string $field): bool => !in_array($field, self::EXCLUDE_FILE_FIELDS, true)
+        );
+
+        // Update the exclude fields with the fields, already added through sys_file, since those take precedence
+        $excludeFields = array_merge($fileFields, self::EXCLUDE_FILE_FIELDS);
+
+        // Get all sys_file_metadata fields expect excluded ones
+        $fileMetaDataFields = array_filter(
+            GeneralUtility::makeInstance(DatabaseRecordList::class)->makeFieldList('sys_file_metadata', false, true),
+            static fn (string $field): bool => !in_array($field, $excludeFields, true)
+        );
+
+        // Merge sys_file and sys_file_metadata fields together, while adding the table name as prefix
+        return array_merge(
+            array_map(static fn (string $value): string => 'sys_file|' . $value, $fileFields),
+            array_map(static fn (string $value): string => 'sys_file_metadata|' . $value, $fileMetaDataFields),
+        );
+    }
+
     protected function htmlResponse(ViewInterface $view): ResponseInterface
     {
         $response = $this->responseFactory