读写c#

时间:2013-08-20 04:30:57

标签: c# file binaryreader binarywriter

我想在c#中读取文件(图像)和另一个文件视频,并在单个txt文件中保存(写入)两个文件的所有内容(1个接一个)。现在我想再次检索第一个图像文件内容和第二个文件内容分开。是否可以读取视频和图像文件以便保存在单个文件中。

3 个答案:

答案 0 :(得分:5)

简短回答:是的,有可能。

长答案:这在很大程度上取决于您的实施。

例如,您可以创建一个holder类,它将二进制文件作为属性接收,序列化它们并提交存储;只要有必要,您只需加载文件并将其反序列化回持有者类的实例。

答案 1 :(得分:0)

...不确定

假设两个输入流infile1infile2具有一个输出流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();
    }
}

答案 2 :(得分: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();