删除文件前几个字节的最快方法 [英] Fastest way to delete the first few bytes of a file
问题描述
我正在使用Windows Mobile Compact Edition 6.5手机,并且正在从蓝牙将二进制数据写到文件中.这些文件变得非常大,超过16M,我需要做的是一旦写入文件,然后就需要在文件中搜索开始字符,然后删除所有内容,从而消除了垃圾.由于图形问题和速度原因,当收到大量数据时,由于无法处理数据而无法进行内联处理,因此传入数据的条件已经太多了.我认为最好发布流程.无论如何,这是我的两难选择,搜索起始字节的速度和文件的重写有时需要5分钟或更长时间...我基本上将文件移到通过它解析的临时文件中,然后重写整个新文件.我必须逐个字节地执行此操作.
I am using a windows mobile compact edition 6.5 phone and am writing out binary data to a file from bluetooth. These files get quite large, 16M+ and what I need to do is to once the file is written then I need to search the file for a start character and then delete everything before, thus eliminating garbage. I cannot do this inline when the data comes in due to graphing issues and speed as I get alot of data coming in and there is already too many if conditions on the incoming data. I figured it was best to post process. Anyway here is my dilemma, speed of search for the start bytes and the rewrite of the file takes sometimes 5mins or more...I basically move the file over to a temp file parse through it and rewrite a whole new file. I have to do this byte by byte.
private void closeFiles() {
try {
// Close file stream for raw data.
if (this.fsRaw != null) {
this.fsRaw.Flush();
this.fsRaw.Close();
// Move file, seek the first sync bytes,
// write to fsRaw stream with sync byte and rest of data after it
File.Move(this.s_fileNameRaw, this.s_fileNameRaw + ".old");
FileStream fsRaw_Copy = File.Open(this.s_fileNameRaw + ".old", FileMode.Open);
this.fsRaw = File.Create(this.s_fileNameRaw);
int x = 0;
bool syncFound = false;
// search for sync byte algorithm
while (x != -1) {
... logic to search for sync byte
if (x != -1 && syncFound) {
this.fsPatientRaw.WriteByte((byte)x);
}
}
this.fsRaw.Close();
fsRaw_Copy.Close();
File.Delete(this.s_fileNameRaw + ".old");
}
} catch(IOException e) {
CLogger.WriteLog(ELogLevel.ERROR,"Exception in writing: " + e.Message);
}
}
必须有比这更快的方法!
There has got to be a faster way than this!
------------使用答案的测试时间-------------
------------Testing times using answer -------------
用1个字节的写入和1个字节的写入来测试我的方式:
Initial Test my way with one byte read and and one byte write:
27 Kb/sec
使用下面的答案和32768字节的缓冲区:
using a answer below and a 32768 byte buffer:
321 Kb/sec
使用下面的答案和65536字节的缓冲区:
using a answer below and a 65536 byte buffer:
501 Kb/sec
推荐答案
您正在按字节复制整个文件.由于种种原因,这可能是无效的.搜索起始偏移量(如果需要,也需要终止偏移量),然后将两个偏移量(或文件的起始偏移量和结束位置)之间的全部内容从一个流复制到另一个流中.
You're doing a byte-wise copy of the entire file. That can't be efficient for a load of reasons. Search for the start offset (and end offset if you need both), then copy from one stream to another the entire contents between the two offsets (or the start offset and end of file).
编辑
您不必阅读全部内容即可制作副本.这样的东西(未经测试,但您知道了)会起作用.
You don't have to read the entire contents to make the copy. Something like this (untested, but you get the idea) would work.
private void CopyPartial(string sourceName, byte syncByte, string destName)
{
using (var input = File.OpenRead(sourceName))
using (var reader = new BinaryReader(input))
using (var output = File.Create(destName))
{
var start = 0;
// seek to sync byte
while (reader.ReadByte() != syncByte)
{
start++;
}
var buffer = new byte[4096]; // 4k page - adjust as you see fit
do
{
var actual = reader.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, actual);
} while (reader.PeekChar() >= 0);
}
}
编辑2
实际上,我今天需要与此类似的东西,因此我决定在不调用PeekChar()的情况下编写它.这是我所做的工作的内核-随时将其与上面的第二个do...while
循环集成.
I actually needed something similar to this today, so I decided to write it without the PeekChar() call. Here's the kernel of what I did - feel free to integrate it with the second do...while
loop above.
var buffer = new byte[1024];
var total = 0;
do
{
var actual = reader.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, actual);
total += actual;
} while (total < reader.BaseStream.Length);
这篇关于删除文件前几个字节的最快方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!