我想在 c# 中读取一个文件(图像)和另一个文件视频,并将两个文件(一个接一个)的所有内容保存(写入)单个 txt 文件中。现在我想再次检索第一个图像文件内容和第二个文件内容分开。是否可以读取视频和图像文件以保存在单个文件中。
问问题
945 次
3 回答
5
简短的回答:是的,这是可能的。
长答案:这在很大程度上取决于您的实施。
例如,您可以创建一个持有者类,它接收两个二进制文件作为属性,将它们序列化并提交到存储;必要时,您只需加载文件并将其反序列化回持有者类的实例。
于 2013-08-20T04:34:33.773 回答
0
我建议您以字节为单位读取文件,构建内容并保存它们:
var FileOne = File.ReadAllBytes(URL).ToList().Select(x=> Convert.ToInt16(x)).ToList();
var FileTwo = File.ReadAllBytes(URL).ToList().Select(x=> Convert.ToInt16(x)).ToList();;
现在
StreamWriter SW = new StreamWriter (URL);
//To structure FileOne
FileOne.ForEach(x=> SW.Write("$(1)"+x+","));
//To structure FileTwo
FileOne.ForEach(x=> SW.Write("$(2)"+x+","));
SW.Close();
请注意,要恢复保存的文件,您必须将其转换回字节模式。
为此,您可以拆分 (',') 并从阅读每个部分开始,可以这样完成。(这不是最好的解决方案,但它工作得非常快)
var Restore = File.ReadAllText(URL).Split(',').ToList();
foreach(var i in Restore) {
if (i.StartsWith("$(1)") {i.Replce("$(1)",""); and Do what you want}
else if (i.StartsWith("$(2)") {i.Replce("$(2)",""); andDo what you want}
}
不要忘记将字符串转换回字节!
.Select(x=> Convert.ToByte(x)).ToList();
于 2013-08-20T05:51:06.557 回答
0
当然...
假设有两个输入流infile1
和infile2
一个输出流outfile1
。我们将指定我们的文件格式为{Infile 1 Length in 8 bytes},{Infile 2 Length in 8 bytes},{Infile 1 data},{Infile 2 data}
public static void Main(string[] args)
{
using (Stream infile1 = File.Open("Foobar.jpg", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream infile2 = File.Open("Foobar.avi", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outfile = File.Open("Out.bin", FileMode.Create, FileAccess.Write, FileShare.None))
{
// write lengths
byte[] file1Len = BitConverter.GetBytes(infile1.Length);
byte[] file2Len = BitConverter.GetBytes(infile2.Length);
outfile.Write(file1Len, 0, 8);
outfile.Write(file2Len, 0, 8);
// write data
infile1.CopyTo(outfile);
infile2.CopyTo(outfile);
}
// read file 1
using (Stream combinedFile = File.Open("out.bin", FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] file1len = new byte[8];
combinedFile.Read(file1len, 0, 8);
long lFile1Len = BitConverter.ToInt64(file1len, 0);
// advance past header
combinedFile.Position = 16;
// limit
var limStream = new LimitedStream(combinedFile, lFile1Len);
// use the file as normal
var bmp = System.Drawing.Bitmap.FromStream(limStream);
bmp.Save(@"C:\drop\demo.jpg");
}
// read file 2
using (Stream combinedFile = File.Open("out.bin", FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] file1len = new byte[8];
combinedFile.Read(file1len, 0, 8);
long lFile1Len = BitConverter.ToInt64(file1len, 0);
byte[] file2len = new byte[8];
combinedFile.Read(file2len, 0, 8);
long lFile2Len = BitConverter.ToInt64(file2len, 0);
// advance past header and first file
combinedFile.Position = 16 + lFile1Len;
// limit
var limStream = new LimitedStream(combinedFile, lFile2Len);
// copy video out
var tempPath = System.IO.Path.GetTempFileName();
using (Stream outStr = File.Open(tempPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
limStream.CopyTo(outStr);
}
}
}
public class LimitedStream : Stream
{
long StartPosition = 0;
long FunctionalLength = 0;
long EndPosition { get { return StartPosition + FunctionalLength; } }
Stream BaseStream = null;
public LimitedStream(Stream baseStream, long length)
{
StartPosition = baseStream.Position;
FunctionalLength = length;
BaseStream = baseStream;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return BaseStream.CanSeek; }
}
public override bool CanWrite
{
get { return false; }
}
public override void Flush()
{
BaseStream.Flush();
}
public override long Length
{
get { return FunctionalLength; }
}
public override long Position
{
get
{
return BaseStream.Position - StartPosition;
}
set
{
BaseStream.Position = value + StartPosition;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (BaseStream.Position + count > EndPosition)
count = (int)(EndPosition - BaseStream.Position);
// if there is no more data, return no read
if (count < 1)
return 0;
return BaseStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
if (origin == SeekOrigin.Current)
return BaseStream.Seek(offset, origin);
else if (origin == SeekOrigin.Begin)
return BaseStream.Seek(offset - StartPosition, origin);
else if (origin == SeekOrigin.End)
return BaseStream.Seek(BaseStream.Length - EndPosition + offset, origin);
else throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
于 2013-08-20T05:07:17.493 回答