我正在使用以下代码将txt文件中写入的十六进制字符串转换为 字节文件。问题是它不处理大型txt文件,我得到了 “内存异常”。我知道它应该以“块”完成,但我不能 做对了。
请帮忙!代码:
protected void Button1_Click(object sender, EventArgs e)
{
{
string tempFileName = (Server.MapPath("~\\Tempfolder\\" + FileUpload2.FileName));
using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(fs))
{
string s = (sr.ReadToEnd());
if (s.Length % 2 == 1) { lblispis.Text = "String must have an even length"; }
else
{
string hexString = s;
File.WriteAllBytes(tempFileName + ".bin", StringToByteArray(hexString));
lblispis.Text = "Done.";
}
}
}
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
答案 0 :(得分:2)
如果文件格式允许,您可以将ReadToEnd
调用替换为ReadLine
并将其包装在一个循环中。
如果不是这种情况,那么在您到达文件末尾之前,始终可以选择读取偶数个字符(Read(char[], int, int)
)。当然,这样你在完成了一些工作后很晚就发现了不均匀的字符数。
答案 1 :(得分:1)
要添加@Wormbo的答案,请注意十六进制字符串只包含两倍于字节数组的字符。在.NET中,对象大小限制为2GB(2GB实际上是32位计算机上的进程大小限制),但由于堆碎片,您甚至可能很容易分配大约800MB的连续块。
换句话说,您需要在转换后立即直接写入磁盘:
using (StreamReader reader = new StreamReader(hex))
using (BinaryWriter writer = new BinaryWriter(File.Open(bin, FileMode.Create)))
{
string line;
while ((line = reader.ReadLine()) != null)
writer.Write(StringToByteArray(line));
}
<强> [编辑] 强>
我已修复它,必须在作业周围添加括号(查看上面的while
语句。)
请注意,这只是以下内容的简写:
string line = reader.ReadLine();
while (line != null)
{
writer.Write(...);
line = reader.ReadLine();
}