如何读取包含一行多条记录的文件-C#
我有一个只有一行的文本文件。每个文件包含一个客户名称,但包含多个项目和说明。如何读取包含一行多条记录的文件-C#,c#,asp.net,filestream,C#,Asp.net,Filestream,我有一个只有一行的文本文件。每个文件包含一个客户名称,但包含多个项目和说明。 以00(公司名称)开头的记录的字符长度为10 01(项目#)-字符长度为10 02(说明)-字符长度为50 我知道如何读取文件,但我不知道如何仅循环一行,查找记录00、01、02并根据长度抓取文本,最后从最后一条记录的位置开始,然后再次开始循环。有人能告诉我怎么读这样的文件吗 输出: companyName 16622 Description companyName 15522
以00(公司名称)开头的记录的字符长度为10
01(项目#)-字符长度为10
02(说明)-字符长度为50
我知道如何读取文件,但我不知道如何仅循环一行,查找记录00、01、02并根据长度抓取文本,最后从最后一条记录的位置开始,然后再次开始循环。有人能告诉我怎么读这样的文件吗 输出:
companyName 16622 Description
companyName 15522 Description
输入文本文件示例
00Init 0115522 02Description 0116622 02Description
如果将整个文件读入一个字符串,则有几个选项 第一,它可能有用
另一个选择是使用。一旦有了索引,就可以使用string.substring。如果将整个文件读入一个字符串,则有两个选项 第一,它可能有用
另一个选择是使用。一旦有了索引,就可以使用string.substring,您必须根据分隔符拆分行。在您的例子中,似乎使用了空格作为分隔符 您正在寻找的方法是String.Split(),它应该满足您的需要:)文档位于-它还包括示例 我会这样做:
string myLineOfText = "MyCompany 12345 The description of my company";
string[] partsOfMyLine = myLineOfText.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
// should be from a file but this is just an example
string[] lines = {
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
};
// loop through each line
// (lines can have multiple items)
foreach (string line in lines)
{
Client client = Parser.ParseData (line);
Console.WriteLine ("Read: " + client.name);
}
祝你好运!:) 必须根据分隔符拆分行。在您的例子中,似乎使用了空格作为分隔符 您正在寻找的方法是String.Split(),它应该满足您的需要:)文档位于-它还包括示例 我会这样做:
string myLineOfText = "MyCompany 12345 The description of my company";
string[] partsOfMyLine = myLineOfText.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
// should be from a file but this is just an example
string[] lines = {
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
"00XXXXXXXXXX01YYYYYYYYYY02XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXX.XXXXXXXXXX",
};
// loop through each line
// (lines can have multiple items)
foreach (string line in lines)
{
Client client = Parser.ParseData (line);
Console.WriteLine ("Read: " + client.name);
}
祝你好运!:) 假设指定了固定的宽度,让我们创建两个简单的类来保存客户机及其相关数据作为列表:
// can hold as many items (data) as there are in the line
public class Client
{
public string name;
public List<ClientData> data;
};
// one single item in the client data
public class ClientData
{
public string code;
public string description;
};
假设指定了固定宽度,让我们创建两个简单类,以将客户机及其相关数据作为列表保存:
// can hold as many items (data) as there are in the line
public class Client
{
public string name;
public List<ClientData> data;
};
// one single item in the client data
public class ClientData
{
public string code;
public string description;
};
此解决方案假定数据是固定宽度的,并且项目编号将在描述之前(01在02之前)。此解决方案将在每次遇到描述记录时发出一条记录,并处理同一公司的多个产品 首先,定义一个类来保存数据:
public class Record
{
public string CompanyName { get; set; }
public string ItemNumber { get; set; }
public string Description { get; set; }
}
然后,遍历字符串,在获得描述后返回一条记录:
public static IEnumerable<Record> ReadFile(string input)
{
// Alter these as appropriate
const int RECORDTYPELENGTH = 2;
const int COMPANYNAMELENGTH = 41;
const int ITEMNUMBERLENGTH = 8;
const int DESCRIPTIONLENGTH = 48;
int index = 0;
string companyName = null;
string itemNumber = null;
while (index < input.Length)
{
string recordType = input.Substring(index, RECORDTYPELENGTH);
index += RECORDTYPELENGTH;
if (recordType == "00")
{
companyName = input.Substring(index, COMPANYNAMELENGTH).Trim();
index += COMPANYNAMELENGTH;
}
else if (recordType == "01")
{
itemNumber = input.Substring(index, ITEMNUMBERLENGTH).Trim();
index += ITEMNUMBERLENGTH;
}
else if (recordType == "02")
{
string description = input.Substring(index, DESCRIPTIONLENGTH).Trim();
index += DESCRIPTIONLENGTH;
yield return new Record
{
CompanyName = companyName,
ItemNumber = itemNumber,
Description = description
};
}
else
{
throw new FormatException("Unexpected record type " + recordType);
}
}
}
此解决方案假定数据是固定宽度的,并且项目编号将在描述之前(01在02之前)。此解决方案将在每次遇到描述记录时发出一条记录,并处理同一公司的多个产品 首先,定义一个类来保存数据:
public class Record
{
public string CompanyName { get; set; }
public string ItemNumber { get; set; }
public string Description { get; set; }
}
然后,遍历字符串,在获得描述后返回一条记录:
public static IEnumerable<Record> ReadFile(string input)
{
// Alter these as appropriate
const int RECORDTYPELENGTH = 2;
const int COMPANYNAMELENGTH = 41;
const int ITEMNUMBERLENGTH = 8;
const int DESCRIPTIONLENGTH = 48;
int index = 0;
string companyName = null;
string itemNumber = null;
while (index < input.Length)
{
string recordType = input.Substring(index, RECORDTYPELENGTH);
index += RECORDTYPELENGTH;
if (recordType == "00")
{
companyName = input.Substring(index, COMPANYNAMELENGTH).Trim();
index += COMPANYNAMELENGTH;
}
else if (recordType == "01")
{
itemNumber = input.Substring(index, ITEMNUMBERLENGTH).Trim();
index += ITEMNUMBERLENGTH;
}
else if (recordType == "02")
{
string description = input.Substring(index, DESCRIPTIONLENGTH).Trim();
index += DESCRIPTIONLENGTH;
yield return new Record
{
CompanyName = companyName,
ItemNumber = itemNumber,
Description = description
};
}
else
{
throw new FormatException("Unexpected record type " + recordType);
}
}
}
Sample.txt的内容
:
00Company1 0115522 02This is a description for company 1. 00Company2 0115523 02This is a description for company 2. 00Company3 0115524 02This is a description for company 3
请注意,在下面的代码中,字段比原始问题中指定的字段长2个字符。这是因为我将标题包含在每个字段的长度中,因此长度10
的字段通过包含标题中的00
有效地12
。如果不需要这样做,请调整fieldlength
数组中条目的偏移量
String directory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
String file = "Sample.txt";
String path = Path.Combine(directory, file);
Int32[] fieldLengths = new Int32[] { 12, 12, 52 };
List<RowData> rows = new List<RowData>();
Byte[] buffer = new Byte[fieldLengths.Sum()];
using (var stream = File.OpenRead(path))
{
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
List<String> fieldValues = new List<String>();
Int32 offset = 0;
for (int i = 0; i < fieldLengths.Length; i++)
{
var value = Encoding.UTF8.GetString(buffer, offset, fieldLengths[i]);
fieldValues.Add(value);
offset += fieldLengths[i];
}
String companyName = fieldValues[0];
String itemNumber = fieldValues[1];
String description = fieldValues[2];
var row = new RowData(companyName, itemNumber, description);
rows.Add(row);
}
}
结果将出现在
行
变量中。Sample.txt的内容:
00Company1 0115522 02This is a description for company 1. 00Company2 0115523 02This is a description for company 2. 00Company3 0115524 02This is a description for company 3
请注意,在下面的代码中,字段比原始问题中指定的字段长2个字符。这是因为我将标题包含在每个字段的长度中,因此长度10
的字段通过包含标题中的00
有效地12
。如果不需要这样做,请调整fieldlength
数组中条目的偏移量
String directory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
String file = "Sample.txt";
String path = Path.Combine(directory, file);
Int32[] fieldLengths = new Int32[] { 12, 12, 52 };
List<RowData> rows = new List<RowData>();
Byte[] buffer = new Byte[fieldLengths.Sum()];
using (var stream = File.OpenRead(path))
{
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
List<String> fieldValues = new List<String>();
Int32 offset = 0;
for (int i = 0; i < fieldLengths.Length; i++)
{
var value = Encoding.UTF8.GetString(buffer, offset, fieldLengths[i]);
fieldValues.Add(value);
offset += fieldLengths[i];
}
String companyName = fieldValues[0];
String itemNumber = fieldValues[1];
String description = fieldValues[2];
var row = new RowData(companyName, itemNumber, description);
rows.Add(row);
}
}
结果将出现在
行中
变量中。我建议创建一个表示文件中数据字段的类,然后将数据加载/保存到列表对象中。您也可以通过查找如何使用string.Split函数来实现这一点。如果数据始终保证为固定长度且长度不变,则(本例中每条记录70个字符),我会这样做:(1)读取行,(2)获取行的长度,希望是70的倍数,(3)循环使用.substring()
函数拉取字符串的适当部分,然后(4)在循环中使用substring()
再次为每个长度的数据(10、10、50)提取各个部分。字段是否与您指定的长度完全一致?(即,如果没有使用所有可用空间,是否用空格填充?)您说它是一行。但是问题中提供的示例有三行。这是正确的还是所有三行都应该在一行中?是的,字段用空格填充,正是我指定的长度。我建议创建一个表示文件中数据字段的类,然后将数据加载/保存到L中ist object u也可以通过查找如何使用string.Split函数来实现这一点。如果数据始终保证为固定长度,并且长度不会改变(在本例中,每条记录包含70个字符),我会这样做:(1)读取行,(2)获取行的长度,希望是70的倍数,(3)循环70多次进入该长度,使用.substring()
函数提取字符串的适当部分,然后(4)在循环中,再次使用substring()
为每个数据长度(10、10、50)提取各个部分。字段是否正是您指定的长度?(即,如果他们不使用所有可用空间,是否用空格填充?)您说是一行。但是问题中提供的示例有三行。这是正确的还是所有三行都应该在一行中?是的,字段用空格填充,并且长度与我的长度完全相同