限制条件:
1.不能把整个文件所有内容直接读取到内存后拼接重组(文件较大)
2.替换内容长度大于被替换内容
目标示例:
如文件原内容为**12356**,现在要将position位置为4的'3'替换为'34'使最终结果为**123456**,或者删除'3'使最终结果为**1256**。
注:
1.* 意为任意的二进制值
2.希望获取C++或者C#的解决方法代码,有明确解决思路亦可
限制条件:
1.不能把整个文件所有内容直接读取到内存后拼接重组(文件较大)
2.替换内容长度大于被替换内容
目标示例:
如文件原内容为**12356**,现在要将position位置为4的'3'替换为'34'使最终结果为**123456**,或者删除'3'使最终结果为**1256**。
注:
1.* 意为任意的二进制值
2.希望获取C++或者C#的解决方法代码,有明确解决思路亦可
如果替换内容长度>或者<原来的长度。那么,无论你用什么语言,用什么算法,最优化的情况,需要把修改点到文件结尾的文件重新覆盖重写一遍。
因为文件是连续存储在磁盘上的。
如果你可以自己定义文件的格式(也就是说你的文件只由你的程序读取,而不是被别的程序读取),你可以考虑使用链式存储或者稀疏存储,使得替换内容的操作变得高效(代价是浪费一部分存储)
先把原则和你说清楚。
如果你需要写程序,可以写给你。
代码还有一些问题,正在改
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Q1065402
{
class MyLinkedFile : IDisposable
{
private const int EOF = -1;
private const int BOF = 0;
private FileStream fs = null;
private string filename;
private int curr = 0;
private byte[] MakeBytes(int pre, int next, int value)
{
return BitConverter.GetBytes(pre).Concat(BitConverter.GetBytes(next)).Concat(BitConverter.GetBytes(value)).ToArray();
}
private void parseBytes(byte[] arr, out int pre, out int next, out int value)
{
pre = BitConverter.ToInt32(arr, 0);
next = BitConverter.ToInt32(arr, 4);
value = BitConverter.ToInt32(arr, 8);
}
public MyLinkedFile(string fn)
{
if (!File.Exists(fn))
File.WriteAllBytes(fn, MakeBytes(BOF, EOF, 0));
fs = new FileStream(fn, FileMode.OpenOrCreate);
filename = fn;
}
public IEnumerable<int> ReadAll()
{
int pre = 0;
int next = 0;
int value = 0;
curr = -1;
fs.Position = 0;
byte[] data = new byte[12];
fs.Read(data, 0, 12);
parseBytes(data, out pre, out next, out value);
while (true)
{
if (next == EOF) break;
curr++;
fs.Position = next * 12;
fs.Read(data, 0, 12);
parseBytes(data, out pre, out next, out value);
yield return value;
}
}
private void moveToBegin()
{
foreach (var item in ReadAll().Take(1)) ;
}
public void moveToEnd()
{
foreach (var item in ReadAll());
}
public void Append(int val)
{
int pre = 0;
int next = 0;
int value = 0;
byte[] data = new byte[12];
fs.Read(data, 0, 12);
parseBytes(data, out pre, out next, out value);
fs.Position -= 12;
fs.Write(MakeBytes(pre, (int)(fs.Length / 12), value), 0, 12);
pre = (int)fs.Position / 12;
fs.Position = fs.Length;
fs.SetLength(fs.Length + 12);
fs.Write(MakeBytes(pre, next, val), 0, 12);
curr++;
}
public void Dispose()
{
if (fs != null)
{
fs.Close();
fs.Dispose();
fs = null;
filename = "";
}
}
}
class Program
{
static void Main(string[] args)
{
using (MyLinkedFile lf = new MyLinkedFile(@"c:\1.bin"))
{
lf.moveToEnd();
lf.Append(21);
lf.Append(22);
lf.Append(23);
//foreach (var item in lf.ReadAll())
// Console.WriteLine(item);
}
}
}
}