Home Software Articles Photos

7-dee

7-zip modified to be even better.

Physical vs logical path

Rar, 7-zip and 7-dee translate physical paths (on disk) to logical paths (in archive) differently.

7-zip creates logical path either by copying physical path, or by using only filename, if physical path contains c:, \(root), ..\ or .\.
This is not very flexible, 7-zip can't add files with logical paths not starting in current directory.

Rar creates logical path by cropping physical one as little as possible, to get rid of all c:, \(root) and ..\. It silently removes .\.
So you can insert subdir\..\ anywhere in physical path to control how logical path is formed. However, this fails if there is no known subdirectory.
This makes rar flexible, it can add multiple files with logical paths starting in nearly any physical locations in one command.

7-dee creates logical path by cropping physical one as little as possible, to get rid of all c:, \(root), ..\ and .\.
So you can insert .\ anywhere in physical path to control how logical path is formed.
This makes 7-dee the most flexible, it can add multiple files with logical paths starting in any physical locations in one command. It can emulate both 7-zip and rar.

physical pathlogical path
7-ziprar7-dee
a\b.txta\b.txta\b.txta\b.txt
\a\b.txtb.txta\b.txta\b.txt
c:a\b.txtb.txta\b.txta\b.txt
c:\a\b.txtb.txta\b.txta\b.txt
..\a\b.txtb.txta\b.txta\b.txt
a\b\..\c\d.txtd.txtc\d.txtc\d.txt
a\.\b\c.txtc.txta\b\c.txtb\c.txt

Patch 7-zip to become 7-dee
This is version 2, with fixed handling of paths like "//192.168.1.10/foo".
//UString CDirItems::GetLogPath(int index) const
//{
//  const CDirItem &di = Items[index];
//  return GetPrefixesPath(LogParents, di.LogParent, di.Name);
//}
UString CDirItems::GetLogPath(int index) const
{
  int pos;
  UString path = GetPhyPath(index);
  if (path.Length()>=2 && path[1]==':') path.Delete(0,2);
  if (path.Length()>=2 && path[0]=='\\' && path[1]=='\\' && (pos=path.Find('\\',2))>0) path.Delete(0,pos);
  if (path.Length()==0 || path[0]!='\\') path.Insert(0,'\\');
  while ((pos=path.Find(L"\\..\\"))>=0) path.Delete(0,pos+3);
  while ((pos=path.Find(L"\\.\\"))>=0) path.Delete(0,pos+2);
  while (path.Length()>0 && path[0]=='\\') path.Delete(0,1);
  return path;
}

No warranty

I tested it a bit (in complex project where it replaces rar) and it works fine. But stil, I provide it "as is" without any warranty, I did not test everything.

Downloads

References