2011-08-19 139 views
3

请帮助解决此问题。 我想在读完该行后从文件中删除每一行。我们可以像这样删除吗? 我不想使用任何临时文件来执行此过程。从文件中删除行

请帮助我,谢谢。

+0

你为什么要删除行?只有当你的文件是50000以上的行会影响你的速度。阅读时,它会遍历每一行。将其读入一个字符串数组,然后删除该文件或将其清除。如果需要,请阅读剩余的/需要的线路。 – LouwHopley

+0

您的请求是不可能的。拿一张纸,在上面画一些线。现在想象这是一个磁盘上的“文件”。如果您“删除”论文的第一行,您希望发生什么?你想在纸上的同一个地方放置所有其他线吗?那么,什么应该“取代”删除的行?或者您是否想将其他行移动到工作表的顶部?然后你必须阅读它们并在那里写下它们!正如你不能简单地让你的纸张的一部分消失一样,你也不能删除文件中的一部分。 –

+0

伙计们,看起来他正在要求截断“从阅读该行后”。即使您没有截断它(首先找到该行,然后将字节向后复制,然后根据搜索行的长度截断文件),也是如此。 –

回答

4

除非是最后一行,否则不能在没有临时文件的情况下执行此操作。你可以用覆盖文本行(虽然这不像你想象的那么容易,除非行的大小是固定的) - 如果有某种方法可以指示读取文件的某些行应该被忽略,那么这是一个选项。但是不能通过从中间删除数据来减小文件大小。这绝不是大多数文件系统支持的操作。

同样,您不能在文件中插入额外的信息。基本上可用的操作是覆盖,附加和截断。

+0

我确实相信某些操作系统可以截断文件。不过,它不是标准Java运行时的一部分。 –

+2

@Thorbjørn:这就是为什么我在“不是大多数文件系统支持的操作”中包含“最多”的原因。:) –

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; 
} 
+0

哦,它是标记为Java的。哈哈,还有C#给你。翻译成Java留给学生看。 –