从文件中删除行
除非是最后一行,否则不能在没有临时文件的情况下执行此操作。你可以用覆盖文本行(虽然这不像你想象的那么容易,除非行的大小是固定的) - 如果有某种方法可以指示读取文件的某些行应该被忽略,那么这是一个选项。但是不能通过从中间删除数据来减小文件大小。这绝不是大多数文件系统支持的操作。
同样,您不能在文件中插入额外的信息。基本上可用的操作是覆盖,附加和截断。
我确实相信某些操作系统可以截断文件。不过,它不是标准Java运行时的一部分。 –
@Thorbjørn:这就是为什么我在“不是大多数文件系统支持的操作”中包含“最多”的原因。:) –
你绝对可以做到。认为这将是一个挑战和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;
}
哦,它是标记为Java的。哈哈,还有C#给你。翻译成Java留给学生看。 –
你为什么要删除行?只有当你的文件是50000以上的行会影响你的速度。阅读时,它会遍历每一行。将其读入一个字符串数组,然后删除该文件或将其清除。如果需要,请阅读剩余的/需要的线路。 – LouwHopley
您的请求是不可能的。拿一张纸,在上面画一些线。现在想象这是一个磁盘上的“文件”。如果您“删除”论文的第一行,您希望发生什么?你想在纸上的同一个地方放置所有其他线吗?那么,什么应该“取代”删除的行?或者您是否想将其他行移动到工作表的顶部?然后你必须阅读它们并在那里写下它们!正如你不能简单地让你的纸张的一部分消失一样,你也不能删除文件中的一部分。 –
伙计们,看起来他正在要求截断“从阅读该行后”。即使您没有截断它(首先找到该行,然后将字节向后复制,然后根据搜索行的长度截断文件),也是如此。 –