你需要知道的:
.txt
我的應用程式使用一個存在于檔案中的食物資料庫。每種食物有大約170 個資料(2-3 位數字),由制表符分隔,每種食物又由\n分隔,因此該檔案中的每一行都有1種食物的資料。.txt
應用程式目標平臺是Android,它需要離線作業,我使用Unity和c#進行編碼。
我的2個問題是:
- 獲取
.txt
檔案的訪問權限
由于 android 應用程式無法通過以下方式訪問.txt
檔案
$"{Application.DataPath}/textFileName.txt"
我在Inspector中將 .txt 檔案指定為TextAsset
( name :) 。當應用程式第一次啟動時,我將檔案的所有資料加載到一個(名稱:)中,其中包含一個字串串列:txtFile
TextAsset
json
jsonStringList
for (int i = 0; i < amountOfLinesInTextFile; i ); { jsonStringList.Add(txtFile.text.Split('\n')[i]) }
從技術上講,這確實有效,但不幸的txtFile
是總共有大約15000行,這使得它非常慢(Stopwatch
時間for-loop
:≈750000 毫秒,大約12.5 分鐘......)
顯然,在第一次打開應用程式時讓用戶等待那么長時間不是一個選項......
- 在那尋找
jsonList
在該應用程式中,可以通過將多種食物放在一起來制作自己的食物。為此,用戶必須搜索食物,然后可以按結果添加它。
目前,我檢查
for-loop
用戶搜索欄InputField
(名稱:)的輸入是否searchbar
與食物匹配,jsonStringList
并且該食物尚未顯示。如果兩者都為真,我將食物名稱添加到(
List<string>
name :)中results
,這是我用來顯示匹配食物的名稱。(由于食物的資料(包括名稱)由制表位分隔,我用它.Split('\t')
來獲取食物名稱的正確資料)for (int i = 0; i < amountOfLinesInTextFile; i ) { string name = jsonStringList[i].Split('\t')[nameIndex].ToLower(); if (name.Equals(searchBar.text.ToLower()) && !results.Contains(name)) { results.Add(name); } }
再說一遍:這在技術上是可行的,但它也太慢了(即使很難,它也比問題 1快得多)
(Stopwatch
對于for-loop
:≈1600 毫秒)
對于改善這兩個動作的時間的任何幫助,我將非常高興!也許有一種完全不同的方法來處理如此大的 .txt 檔案,但減少時間的每一點都會有所幫助!
uj5u.com熱心網友回復:
15000 不是一個大檔案,真的。你只是做了太多不必要的閱讀/轉換。你需要做一次,快取它(在你的情況下保存在變數中),重用它。
var foodIndex = txtFile
.text
.Split('\n') //get rows
.Select(x=> x.Split('\t')) //get columns for each row
.ToDictionary(x=> x[nameIndex], StringComparer.OrdinalIgnoreCase); //build case-insensitive search index
var myFood = foodIndex["aPpLe"];
這種產Dictionary<string, string[]>
更好的方法
將CSV 格式(您的檔案顯然是 CSV 表)反序列化為POCO行:
public class Food
{
[DataMember(Order=1)] //here is your nameIndex
public string Name {get;set;}
[DataMember(Order=2)]
public int Amount {get;set;}
//...
}
var foodIndex = SomeCSVParse<Food>(txtFile.text)
.ToDictionary(x=> x.Name, StringComparer.OrdinalIgnoreCase);
var myFood = foodIndex["aPpLe"];
這會產生Dictionary<string, Food>
搜索索引,看起來更好,更容易使用。
這樣,所有從字串到 int/double/datetime/etc 的轉換、列的順序、分隔符(逗號、制表符、空格)、文化(如果有 float/double)、高效閱讀、標題等都可以放棄第三方框架。有人在這里做了 - Parsing CSV files in C#, with header
nuget 上還有很多框架,只需從源代碼中選擇較小/流行或復制粘貼的框架 - https://www.nuget.org/packages?q=CSV
并閱讀有關 C# 中資料結構的更多資訊 - https://docs.microsoft.com/en-us/dotnet/standard/collections/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/475318.html