jac*_*nad 49 c# compact-framework
我使用列表来限制文件大小,因为目标在磁盘和RAM中是有限的.这就是我现在正在做的,但有更有效的方法吗?
readonly List<string> LogList = new List<string>();
...
var logFile = File.ReadAllLines(LOG_PATH);
foreach (var s in logFile) LogList.Add(s);
Run Code Online (Sandbox Code Playgroud)
Eva*_*ski 97
var logFile = File.ReadAllLines(LOG_PATH);
var logList = new List<string>(logFile);
Run Code Online (Sandbox Code Playgroud)
由于logFile
是一个数组,您可以将其传递给List<T>
构造函数.这样可以在迭代数组或使用其他IO类时消除不必要的开销.
public List(IEnumerable<T> collection)
{
...
ICollection<T> c = collection as ICollection<T>;
if( c != null) {
int count = c.Count;
if (count == 0)
{
_items = _emptyArray;
}
else {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
Ram*_*Ram 48
对Evan Mulawski的一点回应是为了缩短它
List<string> allLinesText = File.ReadAllLines(fileName).ToList()
Dan*_*den 13
为什么不使用发电机呢?
private IEnumerable<string> ReadLogLines(string logPath) {
using(StreamReader reader = File.OpenText(logPath)) {
string line = "";
while((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像使用列表一样使用它:
var logFile = ReadLogLines(LOG_PATH);
foreach(var s in logFile) {
// Do whatever you need
}
Run Code Online (Sandbox Code Playgroud)
当然,如果你需要一个List<string>
,那么你需要将整个文件内容保存在内存中.真的没办法解决这个问题.
小智 7
您可以通过这种方式简单阅读。
List<string> lines = System.IO.File.ReadLines(completePath).ToList();
Run Code Online (Sandbox Code Playgroud)
如果可能的话不要存储它。如果您记忆力有限,请通读它。您可以使用 StreamReader:
using (var reader = new StreamReader("file.txt"))
{
var line = reader.ReadLine();
// process line here
}
Run Code Online (Sandbox Code Playgroud)
如果您想使用 LINQ,可以将其包装在一个方法中,该方法会在每行读取时生成字符串。
[编辑]
如果您这样做是为了修剪日志文件的开头,您可以通过执行以下操作来避免加载整个文件:
// count the number of lines in the file
int count = 0;
using (var sr = new StreamReader("file.txt"))
{
while (sr.ReadLine() != null)
count++;
}
// skip first (LOG_MAX - count) lines
count = LOG_MAX - count;
using (var sr = new StreamReader("file.txt"))
using (var sw = new StreamWriter("output.txt"))
{
// skip several lines
while (count > 0 && sr.ReadLine() != null)
count--;
// continue copying
string line = "";
while (line = sr.ReadLine() != null)
sw.WriteLine(line);
}
Run Code Online (Sandbox Code Playgroud)
首先,由于File.ReadAllLines
将整个文件加载到字符串数组(string[]
)中,因此复制到列表是多余的.
其次,您必须了解a List
是使用动态数组实现的.这意味着CLR将需要分配和复制多个数组,直到它可以容纳整个文件.由于该文件已经在磁盘上,你可能会考虑交易速度和内存较小的块数据在磁盘上的工作,直接或处理它.
如果你需要将它完全加载到内存中,至少尝试留下一个数组:
string[] lines = File.ReadAllLines("file.txt");
Run Code Online (Sandbox Code Playgroud)如果真的需要a List
,请逐个加载:
List<string> lines = new List<string>();
using (var sr = new StreamReader("file.txt"))
{
while (sr.Peek() >= 0)
lines.Add(sr.ReadLine());
}
Run Code Online (Sandbox Code Playgroud)
注意: List<T>
有一个接受容量参数的构造函数.如果您事先知道行数,则可以通过预先分配数组来防止多次分配:
List<string> lines = new List<string>(NUMBER_OF_LINES);
Run Code Online (Sandbox Code Playgroud)更好的是,避免将整个文件存储在内存中并"动态"处理它:
using (var sr = new StreamReader("file.txt"))
{
string line;
while (line = sr.ReadLine() != null)
{
// process the file line by line
}
}
Run Code Online (Sandbox Code Playgroud)