【问题标题】:Read and write in c# [closed]在c#中读写[关闭]
【发布时间】:2013-08-20 04:30:57
【问题描述】:

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

【问题讨论】:

  • 您可以读取它们,转换为字节数组,然后将它们的文本表示形式保存到文本文件中。如果没有任何进一步的信息,我无法提供更好的细节。

标签: c# file binaryreader binarywriter


【解决方案1】:

简答:是的,有可能。

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

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

【讨论】:

    【解决方案2】:

    当然……

    假设两个输入流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();
        }
    }
    

    【讨论】:

      【解决方案3】:

      我建议您以字节为单位读取文件,构建内容并保存它们:

      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();
      

      【讨论】:

        猜你喜欢
        • 2022-01-17
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多