我正在学习C#,并堆叠在BinaryReader / Writer上。在这种情况下,我如何读取/写入文件:我需要将此数据存储到二进制文件中。 (雪碧类)
public class Sprite
{
public Int32 id; //spriteID
public Int32 size; //sprite byte size
public byte[] dump; //sprite image byte-array
public Sprite()
{
id = 0;
size = 0;
dump = null;
}
}
我通过此功能获取了精灵数据:
public Sprite createSprite(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
Sprite tmpSpr = new Sprite();
image.Save(ms, format);
tmpSpr.dump = ms.ToArray();
tmpSpr.size = tmpSpr.Length;
tmpSpr.id = 1; //just for example
return tmpSpr;
}
}
但是我正在解决这个问题:
public static bool save(string filename)
{
FileStream fileStream = new FileStream(filename, FileMode.Create);
MemoryStream ms = new MemoryStream();
BinaryWriter wr = new BinaryWriter(ms);
//How i am should write a sprites here?
}
这里未完成的阅读器功能。也堆叠阅读。
public static bool load(string filename, ref Dictionary<UInt32, Sprite> sprites)
{
FileStream fileStream = new FileStream(filename, FileMode.Open);
try
{
using (BinaryReader reader = new BinaryReader(fileStream))
{
UInt32 totalSprites = reader.ReadUInt32(); //total sprites in file
//something like that?
List<UInt32> spriteIndexes = new List<UInt32>();
for (uint i = 0; i < totalSprites; ++i)
{
UInt32 index = reader.ReadUInt32();
spriteIndexes.Add(index);
}
UInt32 id = 1;
foreach (UInt32 element in spriteIndexes)
{
//i am not sure here =(
reader.BaseStream.Seek(element, SeekOrigin.Begin);
UInt32 size = reader.ReadUInt32();
Sprite sprite;
if (sprites.TryGetValue(id, out sprite))
{
if (sprite != null && size > 0)
{
if (sprite.size > 0)
{
//generate warning
}
else
{
sprite.id = id;
sprite.size = size;
sprite.dump = reader.ReadBytes(size);
sprites[id] = sprite;
}
}
}
else
{
//i am not shure here too.
reader.BaseStream.Seek(size, SeekOrigin.Current);
}
++id;
}
}
}
finally
{
fileStream.Close();
}
return true;
}
Sprite文件应具有totalSprites参数,以及所有sprite的列表及其ID,大小和转储。加载功能“似乎”几乎“完成”,但我不知道如何为该“阅读器”写入文件。请显示解决方案。感谢前进!
您的基本问题是,直到您将其写入文件之前,您都不知道该精灵在文件中的位置(除非您可能要遍历数组并计算字节数),但是您想在前面写入索引的精灵。您有几种选择:
首先,为什么要有一个索引?如果您知道有多少个精灵,则只需写入该编号,然后依次读取文件即可,一次仅一个精灵。那是最简单的:
using (var fs = File.OpenWrite(filename))
{
using (var writer = new BinaryWriter(fs))
{
// write sprite count
writer.Write(spriteList.Count);
// and write each sprite
foreach (var s in spriteList)
{
writer.Write(sprite.id);
writer.Write(sprite.size);
writer.Write(sprite.dump);
}
}
}
读取只是相反的:读取计数,然后读取那么多精灵。除非您希望能够读取第五个精灵,而不必先读取前四个精灵,否则并不需要索引。
如果确实需要索引,则可以为它编写一个占位符,然后编写精灵,跟踪其位置,然后返回文件的开头并编写真实索引。像这样:
var index = new List<long>(spriteList.Count);
using (var fs = File.OpenWrite(filename))
{
using (var writer = new BinaryWriter(fs))
{
// write sprite count
writer.Write(spriteList.Count);
var indexPos = writer.BaseStream.Position;
// write index placeholder
for (var i = 0; i < spriteList.Count; ++i)
{
writer.Write(0L);
}
// and write each sprite
for (var i = 0; i < spriteList.Count ++i)
{
// save current position
writer.Flush();
index[i] = writer.BaseStream.Position;
writer.Write(sprite.id);
writer.Write(sprite.size);
writer.Write(sprite.dump);
}
// Seek back to the index position
writer.Flush();
writer.BaseStream.Position = indexPos;
// and write the real index
foreach (var pos in index)
{
writer.Write(pos);
}
}
}
[另一种选择是先编写精灵,并如上所述跟踪它们在索引数组中的位置,但要编写索引after精灵。然后,要读取该文件,请从文件的开头读取子画面计数,将其乘以8(long
的大小),然后减至文件末尾减去该值。那是:
var spriteCount = reader.ReadInt32();
long indexSize = spriteCount * 8;
reader.BaseStream.Seek(-indexSize, SeekOrigin.End);
// now read the index of spriteCount values
我需要启用将图像文件转换为PDF文件的功能。每当用户保存任何格式的图像文件时,都应将其保存为PDF文件。
我已经使用二进制读取器和写入器读取图像并另存为pdf,但是PDF文件已损坏。
您能否协助我使用二进制阅读器读取图像文件,并使用二进制写入器将其另存为pdf文件,而又不会损坏文件?