请帮忙解决这个问题。 我想在读取该行后删除文件中的每一行。我们可以这样删除吗? 我不想使用任何临时文件来执行此过程。
请帮帮我,谢谢。
答案 0 :(得分:4)
如果没有临时文件,则无法执行此操作,除非它是最后一行。您可以覆盖文本行(虽然这并不像您想象的那么容易,除非行是一个固定的大小) - 如果有某种方法可以指示任何读取文件的行应该是忽略了,这是一个选择。但是,您无法通过从中间删除数据来减小文件大小。它绝不是大多数文件系统支持的操作。
同样,您无法在文件中间插入额外信息。基本上可用的操作是覆盖,追加和截断。
答案 1 :(得分:0)
你绝对可以做到。认为这将是System.Text.Encoding
ninjitsu的挑战和良好考验。你走了:
static bool DeleteEveryLineAfter(Stream data, string search, Encoding encoding)
{
const int WindowsPageSize = 4096;
var decoder = encoding.GetDecoder();
var encoder = encoding.GetEncoder();
var buffer = new byte[WindowsPageSize];
var length = 0;
var searchPosition = 0;
var newLine = Environment.NewLine.ToCharArray();
var newLinePosition = 0;
var currentLinePosition = 0;
var lineIsValid = true;
while ((length = data.Read(buffer, 0, WindowsPageSize)) != 0)
{
// Get the characters.
var chars = new char[decoder.GetCharCount(buffer, 0, length, false)];
decoder.GetChars(buffer, 0, length, chars, 0, false);
for (var i = 0; i < chars.Length; i++)
{
var c = chars[i];
if (
// Only if the line isn't LONGER than what we are searching for.
searchPosition < search.Length &&
// And if the current character matches.
search[searchPosition] == c &&
// And we have matched something in it, or it is the start of the line.
(searchPosition > 0 || currentLinePosition == 0) &&
// And if a previous character didn't fail.
lineIsValid
)
{
searchPosition++;
newLinePosition = 0;
}
else if (newLinePosition < newLine.Length && c == newLine[newLinePosition])
{
newLinePosition++;
// Did we match the whole newline.
if (newLinePosition == newLine.Length)
{
// Was the current line a match?
if (lineIsValid && searchPosition == search.Length)
{
// Figure out the different between the amount of data
// we read, and how long the line was.
var bytesLeft = encoder.GetByteCount(chars, i, chars.Length - i, true);
var finalLength = data.Position - bytesLeft;
data.SetLength(finalLength);
return true;
}
else
{
lineIsValid = true;
newLinePosition = 0;
searchPosition = 0;
currentLinePosition = -1; // Compensate for ++ below.
}
}
}
else
{
lineIsValid = false;
}
currentLinePosition++;
}
}
return false;
}