I want to mount the archive (preferably 7z, but you can have another good one) as a virtual disk in Windows. The following conditions must be met:

  1. We believe that there is an empty archive. When it is created is not important.
  2. This archive is mounted as a virtual disk.
  3. There will be exactly one file on this disc.
  4. Compression should occur directly during recording.
  5. The recording will be consistent (but NOT realtime).
  6. Expected recordable volume is from 100 GB to 500 GB.
  7. The expected archive size is 500 times less than the size of the recorded file.
  8. There is not enough free space on the discs to fit the uncompressed file.
  9. It is desirable that sequential reading after writing is also possible.

Uncompressed avi will be recorded, and it must be done under Windows.

With what programs can this be done?

I note that 7zip can do streaming archiving. For example, the following command can pack the displayed text into the cmd.7z archive under the name (file) help.txt ( -si ):

 cmd /? | "C:\Program Files (x86)\7-Zip\7z.exe" a -sihelp.txt cmd.7z 

It turns out that any program that is able to create a virtual disk and output everything that is written to a file on this disk to stdout is suitable.

PS: This question is in English.

  • Not the answer to the question, but Far (and probably Total Commander) can represent the archive as a virtual file system. - VladD
  • @VladD, I need streaming recording with immediate archiving of a single file from an application that does not know how. The question is not about viewing, but about recording (the first 4 points are required). - Qwertiy
  • Yeah, I understand. Therefore, the answer is not: - \ - VladD
  • 2
  • one
    You cannot compress a video file 500 times with a regular archiver. It just does not work . You need to find a video codec. - Pavel Mayorov

1 answer 1

You can try to use WebDAV. Windows can mount WebDAV folders as network drives.

You can start with such a server (C # code), which emulates a blank disk, waiting for the file to be transferred to it:

 using System; using System.Globalization; using System.IO; using System.Net; using System.Xml.Linq; namespace HttpPipe { static class Program { static readonly Uri ListenUri = new Uri("http://localhost/share/"); static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-US"); var listener = new HttpListener { Prefixes = { $"{ListenUri.Scheme}://*:{ListenUri.Port}{ListenUri.PathAndQuery}" }, }; listener.Start(); bool processing = false; try { while (true) { processing = false; var ctx = listener.GetContext(); processing = true; try { var uri = ctx.Request.Url; Console.Error.WriteLine($"{ctx.Request.HttpMethod} {uri} {ctx.Request.ContentType} {ctx.Request.ContentLength64}"); var root = new Uri(uri, ListenUri.PathAndQuery); if (uri + "/" == root.ToString()) uri = root; uri = uri.MakeRelativeUri(root); if (uri.IsAbsoluteUri || uri.ToString().StartsWith("..")) throw new Exception("Неправильный URI: " + uri); if (ProcessContext(ctx, uri.ToString())) break; } finally { ctx.Response.Close(); } } } catch (Exception ex) when (processing) { Console.Error.WriteLine("ERROR: " + ex); } catch (Exception) { } listener.Stop(); } static readonly XNamespace DAV = "DAV:"; private static bool ProcessContext(HttpListenerContext ctx, string uri) { ctx.Response.SendChunked = false; switch (ctx.Request.HttpMethod) { case "OPTIONS": ctx.Response.SetStatus(HttpStatusCode.OK); ctx.Response.AddHeader("DAV", "1"); break; case "PROPFIND": if (uri != "") { ctx.Response.SetStatus(HttpStatusCode.NotFound); } else { var prop = new XElement(DAV + "prop"); prop.SetElementValue(DAV + "creationdate", DateTime.UtcNow.ToString("s") + "Z"); prop.SetElementValue(DAV + "getlastmodified", DateTime.UtcNow.ToString("R")); prop.SetElementValue(DAV + "displayname", "share"); prop.Add(new XElement(DAV + "resourcetype", new XElement(DAV + "collection"))); var response = new XElement(DAV + "response"); response.SetElementValue(DAV + "href", ListenUri.PathAndQuery); response.Add(new XElement(DAV + "propstat", new XElement(DAV + "status", "HTTP/1.1 200 OK"), prop)); ctx.Response.StatusCode = 207; ctx.Response.StatusDescription = "Multi Status"; ctx.Response.Send(new XElement(DAV + "multistatus", new XAttribute(XNamespace.Xmlns + "d", DAV), response)); } break; case "PUT": if (ctx.Request.ContentLength64 > 0) { foreach (string header in ctx.Request.Headers) { Console.Error.WriteLine($" {header}: {ctx.Request.Headers[header]}"); } using (var output = Console.OpenStandardOutput()) { ctx.Request.InputStream.CopyTo(output); } ctx.Response.SetStatus(HttpStatusCode.NoContent); return true; } ctx.Response.SetStatus(HttpStatusCode.NoContent); return false; default: ctx.Response.SetStatus(HttpStatusCode.NotImplemented); break; } return false; } static void SetStatus(this HttpListenerResponse resp, HttpStatusCode status) { resp.StatusCode = (int)status; resp.StatusDescription = status.ToString(); } static void Send(this HttpListenerResponse resp, XElement content) { var ms = new MemoryStream(); content.Save(ms); ms.Position = 0; resp.ContentType = "application/xml; charset=utf-8"; resp.ContentLength64 = ms.Length; ms.CopyTo(resp.OutputStream); } } } 

When a file arrives, it displays its contents in standard output and exits.

Useful links: