如何创建一个包含两种类型文件的类,以便它们相互链接?



我想做一个表,列出2种类型的文件链接在一起。一种是。mp3文件,另一种是。txt文件。我希望将这些文件链接在一起,以便当foreach循环遍历它们时,具有相同名称的文件共享一行。这样可以播放mp3文件,并打开相应的文本文件。

App.razorPage有一个显示文件夹中所有文件的表,但它不考虑两种类型的文件是否共享相同的名称。有没有人可以帮助如何使一个类的文件链接在一起,以便他们可以在表中调用?

代码如下:

<table class="table table-striped mb-0">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var file in textList)
{
<tr>
<td>
@file.Name
</td>
<td>
<span @onclick="() => PlayAudio(file.Url)"
class="text-primary oi oi-play-circle me-2" aria-hidden="true" role="button">
</span>
<span @onclick="() => DeleteAudio(file)"
class="text-danger oi oi-trash" aria-hidden="true" role="button">
</span>
<span @onclick="() => openTextFile(file)"
><button>Open</button>
</span>
</td>
</tr>
}
}
</tbody>
</table>
@code{
readonly List<TextFile> textList = new();
readonly string FolderName = "textSoundFiles";
protected override void OnInitialized()
{
var path = $"{env.WebRootPath}\{FolderName}\";
var files = new DirectoryInfo(path).GetFiles();
foreach (var file in files)
{
textList.Add(new TextFile
{
Name = file.Name,
Url = $"/textFiles/{file.Name}",
Path = file.FullName
});
}
}
public class TextFile
{
public string Name { get; set; }
public string Url { get; set; }
public string Path { get; set; }
}
}

我想做一个表,列出文件,这让我从列出的音频文件播放音频。我正试着目录中的2种文件类型,这样具有相同名称的文件(不包括其MIME类型)彼此链接

使用LinqGroupBy

@foreach(var fileGroup in myFilesGroupedAndSorted)
{
<h3>@fileGroup.Key</h3>
@foreach(var file in fileGroup.OrderBy( file => file.Path))
{
<div>@file.Path</div>
}
}
@code {
// without access to your folder I generated random data.
List<TextFile> myList = new List<TextFile>
{
new TextFile { Name = "", Path = "some-path\SomeFile1.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile2.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile3.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile4.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile5.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile6.txt", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile1.mp3", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile2.mp3", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile3.mp3", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile4.mp3", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile5.mp3", Url = "" },
new TextFile { Name = "", Path = "some-path\SomeFile6.mp3", Url = "" },
};

IEnumerable<IGrouping<string, TextFile>> myFilesGroupedAndSorted
=> myList.GroupBy(file => GetPathWithoutExtension(file.Path))
.OrderBy(group => group.Key);
private string GetPathWithoutExtension(string path)
{
return System.IO.Path.ChangeExtension(path, null);
}
}

通过测试每个文件扩展名来处理每个组应该是微不足道的。我将制作一个子组件来传递IGrouping<string, TextFile>作为参数,以简化逻辑…

Mp3.Razor

<tr>
<td>
@FileGroup.Key
</td>
<td>
@if (Mp3 is not null)
{
<span @onclick="() => PlayAudio(Mp3.Url)"
class="text-primary oi oi-play-circle me-2" aria-hidden="true" role="button">
</span>
<span @onclick="() => DeleteAudio(FileGroup.Key)"
class="text-danger oi oi-trash" aria-hidden="true" role="button">
</span>
}
@if (Text is not null)
{
<span @onclick="() => openTextFile(Text)">
<button>Open</button>
</span>
}
</td>
</tr>
@code {
[Parameter]
public IGrouping<string, TextFile> FileGroup { get; set; } = default!;
TextFile? Text => FileGroup.FirstOrDefault(file => Path.GetExtension(file.Path).ToLower() == "txt");
TextFile? Mp3 => FileGroup.FirstOrDefault(file => Path.GetExtension(file.Path).ToLower() == "mp3");
}
...
<tbody>
@foreach(var fileGroup in myFilesGroupedAndSorted)
{
<Mp3 FileGroup=fileGroup /> 
}
</tbody>
...

你需要"pivot"该表,即将列表转换为表。LINQ可以用于此。看看这个答案。而不是"jan";和";Feb"您将拥有属性bool HasMp3bool HasTxt,以及适当的Where子句。像这样:

var files = new DirectoryInfo(path).GetFiles();
textList.AddRange(files
.GroupBy(c => Path.ChangeExtension(c.Name, null))
.Select(g => new TextFile() {
Name = g.Key,
Url = $"/textFiles/{g.Key}",
HasMp3 = g.Any(c => Path.GetExtension(c) == ".mp3"),
HasTxt = g.Any(c => Path.GetExtension(c) == ".txt"),
}));

使用这两个bool属性,如果对应的文件不存在,您可以隐藏按钮。Url属性没有扩展名。您必须在每个适当的函数中附加每个适当的扩展名。