aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clarke Casey2009-03-06 20:12:08 +0000
committerJustin Clarke Casey2009-03-06 20:12:08 +0000
commit85774de2310141f4311bc3df1946d44df9ddde59 (patch)
treee86febe5873121d9a529f6d77a2a7ee929030425 /OpenSim
parent* Protects RestClient from crashing with dictionary exception, which leads to... (diff)
downloadopensim-SC-85774de2310141f4311bc3df1946d44df9ddde59.zip
opensim-SC-85774de2310141f4311bc3df1946d44df9ddde59.tar.gz
opensim-SC-85774de2310141f4311bc3df1946d44df9ddde59.tar.bz2
opensim-SC-85774de2310141f4311bc3df1946d44df9ddde59.tar.xz
* Improve memory usage when writing OARs
* This should make saving large OARs a somewhat better experience * However, the problem where saving an archive pulls large numbers of assets into the asset cache isn't yet resolved * This patch also removes lots of archive writing spam that crept in
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs98
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs8
6 files changed, 68 insertions, 76 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 357ed40..b0f2742 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 protected TarArchiveWriter archive = new TarArchiveWriter(); 48 protected TarArchiveWriter m_archive;
49 protected UuidGatherer m_assetGatherer; 49 protected UuidGatherer m_assetGatherer;
50 protected Dictionary<UUID, int> assetUuids = new Dictionary<UUID, int>(); 50 protected Dictionary<UUID, int> assetUuids = new Dictionary<UUID, int>();
51 51
@@ -87,14 +87,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
87 protected void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids) 87 protected void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids)
88 { 88 {
89 AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound); 89 AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound);
90 assetsArchiver.Archive(archive); 90 assetsArchiver.Archive(m_archive);
91 91
92 Exception reportedException = null; 92 Exception reportedException = null;
93 bool succeeded = true; 93 bool succeeded = true;
94 94
95 try 95 try
96 { 96 {
97 archive.WriteTar(m_saveStream); 97 m_archive.Close();
98 } 98 }
99 catch (IOException e) 99 catch (IOException e)
100 { 100 {
@@ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
172 172
173 writer.WriteEndElement(); 173 writer.WriteEndElement();
174 174
175 archive.AddFile(filename, sw.ToString()); 175 m_archive.WriteFile(filename, sw.ToString());
176 176
177 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, assetUuids); 177 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, assetUuids);
178 } 178 }
@@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
185 inventoryFolder.Name, 185 inventoryFolder.Name,
186 InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, 186 InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
187 inventoryFolder.ID); 187 inventoryFolder.ID);
188 archive.AddDir(path); 188 m_archive.WriteDir(path);
189 189
190 List<InventoryFolderImpl> childFolders = inventoryFolder.RequestListOfFolderImpls(); 190 List<InventoryFolderImpl> childFolders = inventoryFolder.RequestListOfFolderImpls();
191 List<InventoryItemBase> items = inventoryFolder.RequestListOfItems(); 191 List<InventoryItemBase> items = inventoryFolder.RequestListOfItems();
@@ -279,6 +279,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
279 { 279 {
280 inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); 280 inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
281 } 281 }
282
283 m_archive = new TarArchiveWriter(m_saveStream);
282 284
283 if (null == inventoryFolder) 285 if (null == inventoryFolder)
284 { 286 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
index b5aa0f3..cc4eadb 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
@@ -85,17 +85,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
85 85
86 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time."); 86 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
87 87
88 TarArchiveWriter archive = new TarArchiveWriter(); 88 TarArchiveWriter archive = new TarArchiveWriter(m_saveStream);
89 89
90 // Write out control file 90 // Write out control file
91 archive.AddFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile()); 91 archive.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile());
92 92
93 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 93 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
94 94
95 // Write out region settings 95 // Write out region settings
96 string settingsPath 96 string settingsPath
97 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName); 97 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
98 archive.AddFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings)); 98 archive.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
99 99
100 m_log.InfoFormat("[ARCHIVER]: Added region settings to archive."); 100 m_log.InfoFormat("[ARCHIVER]: Added region settings to archive.");
101 101
@@ -105,7 +105,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
105 105
106 MemoryStream ms = new MemoryStream(); 106 MemoryStream ms = new MemoryStream();
107 m_terrainModule.SaveToStream(terrainPath, ms); 107 m_terrainModule.SaveToStream(terrainPath, ms);
108 archive.AddFile(terrainPath, ms.ToArray()); 108 archive.WriteFile(terrainPath, ms.ToArray());
109 ms.Close(); 109 ms.Close();
110 110
111 m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive."); 111 m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive.");
@@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
125 Math.Round(position.X), Math.Round(position.Y), Math.Round(position.Z), 125 Math.Round(position.X), Math.Round(position.Y), Math.Round(position.Z),
126 sceneObject.UUID); 126 sceneObject.UUID);
127 127
128 archive.AddFile(filename, serializedObject); 128 archive.WriteFile(filename, serializedObject);
129 } 129 }
130 130
131 m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive."); 131 m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
134 AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound); 134 AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound);
135 assetsArchiver.Archive(archive); 135 assetsArchiver.Archive(archive);
136 136
137 archive.WriteTar(m_saveStream); 137 archive.Close();
138 138
139 m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_scene.RegionInfo.RegionName); 139 m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_scene.RegionInfo.RegionName);
140 140
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
index e863188..8debfcf 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
@@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
110 110
111 xtw.WriteEndDocument(); 111 xtw.WriteEndDocument();
112 112
113 archive.AddFile("assets.xml", sw.ToString()); 113 archive.WriteFile("assets.xml", sw.ToString());
114 } 114 }
115 115
116 /// <summary> 116 /// <summary>
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
141 asset.Type, asset.ID); 141 asset.Type, asset.ID);
142 } 142 }
143 143
144 archive.AddFile( 144 archive.WriteFile(
145 ArchiveConstants.ASSETS_PATH + uuid.ToString() + extension, 145 ArchiveConstants.ASSETS_PATH + uuid.ToString() + extension,
146 asset.Data); 146 asset.Data);
147 147
diff --git a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
index 19d2629..070f597 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
@@ -38,7 +38,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
38 /// </summary> 38 /// </summary>
39 public class TarArchiveReader 39 public class TarArchiveReader
40 { 40 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 42
43 public enum TarEntryType 43 public enum TarEntryType
44 { 44 {
@@ -113,14 +113,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
113 { 113 {
114 int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11); 114 int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
115 tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength)); 115 tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength));
116 m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath); 116 //m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
117 header = m_br.ReadBytes(512); 117 header = m_br.ReadBytes(512);
118 } 118 }
119 else 119 else
120 { 120 {
121 tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100); 121 tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
122 tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray); 122 tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
123 m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath); 123 //m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
124 } 124 }
125 125
126 tarHeader.FileSize = ConvertOctalBytesToDecimal(header, 124, 11); 126 tarHeader.FileSize = ConvertOctalBytesToDecimal(header, 124, 11);
@@ -168,14 +168,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
168 { 168 {
169 byte[] data = m_br.ReadBytes(fileSize); 169 byte[] data = m_br.ReadBytes(fileSize);
170 170
171 m_log.DebugFormat("[TAR ARCHIVE READER]: fileSize {0}", fileSize); 171 //m_log.DebugFormat("[TAR ARCHIVE READER]: fileSize {0}", fileSize);
172 172
173 // Read the rest of the empty padding in the 512 byte block 173 // Read the rest of the empty padding in the 512 byte block
174 if (fileSize % 512 != 0) 174 if (fileSize % 512 != 0)
175 { 175 {
176 int paddingLeft = 512 - (fileSize % 512); 176 int paddingLeft = 512 - (fileSize % 512);
177 177
178 m_log.DebugFormat("[TAR ARCHIVE READER]: Reading {0} padding bytes", paddingLeft); 178 //m_log.DebugFormat("[TAR ARCHIVE READER]: Reading {0} padding bytes", paddingLeft);
179 179
180 m_br.ReadBytes(paddingLeft); 180 m_br.ReadBytes(paddingLeft);
181 } 181 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
index 09ea7ec..506fcc5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
@@ -39,65 +39,80 @@ namespace OpenSim.Region.CoreModules.World.Archiver
39 { 39 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 41
42 protected Dictionary<string, byte[]> m_files = new Dictionary<string, byte[]>();
43
44 protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); 42 protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
45 43
46 /// <summary> 44 /// <summary>
47 /// Add a directory to the tar archive. We can only handle one path level right now! 45 /// Binary writer for the underlying stream
46 /// </summary>
47 protected BinaryWriter m_bw;
48
49 public TarArchiveWriter(Stream s)
50 {
51 m_bw = new BinaryWriter(s);
52 }
53
54 /// <summary>
55 /// Write a directory entry to the tar archive. We can only handle one path level right now!
48 /// </summary> 56 /// </summary>
49 /// <param name="dirName"></param> 57 /// <param name="dirName"></param>
50 public void AddDir(string dirName) 58 public void WriteDir(string dirName)
51 { 59 {
52 // Directories are signalled by a final / 60 // Directories are signalled by a final /
53 if (!dirName.EndsWith("/")) 61 if (!dirName.EndsWith("/"))
54 dirName += "/"; 62 dirName += "/";
55 63
56 AddFile(dirName, new byte[0]); 64 WriteFile(dirName, new byte[0]);
57 } 65 }
58 66
59 /// <summary> 67 /// <summary>
60 /// Add a file to the tar archive 68 /// Write a file to the tar archive
61 /// </summary> 69 /// </summary>
62 /// <param name="filePath"></param> 70 /// <param name="filePath"></param>
63 /// <param name="data"></param> 71 /// <param name="data"></param>
64 public void AddFile(string filePath, string data) 72 public void WriteFile(string filePath, string data)
65 { 73 {
66 AddFile(filePath, m_asciiEncoding.GetBytes(data)); 74 WriteFile(filePath, m_asciiEncoding.GetBytes(data));
67 } 75 }
68 76
69 /// <summary> 77 /// <summary>
70 /// Add a file to the tar archive 78 /// Write a file to the tar archive
71 /// </summary> 79 /// </summary>
72 /// <param name="filePath"></param> 80 /// <param name="filePath"></param>
73 /// <param name="data"></param> 81 /// <param name="data"></param>
74 public void AddFile(string filePath, byte[] data) 82 public void WriteFile(string filePath, byte[] data)
75 { 83 {
76 m_files[filePath] = data; 84 if (filePath.Length > 100)
85 WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
86
87 char fileType;
88
89 if (filePath.EndsWith("/"))
90 {
91 fileType = '5';
92 }
93 else
94 {
95 fileType = '0';
96 }
97
98 WriteEntry(filePath, data, fileType);
77 } 99 }
78 100
79 /// <summary> 101 /// <summary>
80 /// Write the raw tar archive data to a stream. The stream will be closed on completion. 102 /// Finish writing the raw tar archive data to a stream. The stream will be closed on completion.
81 /// </summary> 103 /// </summary>
82 /// <param name="s">Stream to which to write the data</param> 104 /// <param name="s">Stream to which to write the data</param>
83 /// <returns></returns> 105 /// <returns></returns>
84 public void WriteTar(Stream s) 106 public void Close()
85 { 107 {
86 BinaryWriter bw = new BinaryWriter(s);
87
88 foreach (string filePath in m_files.Keys)
89 {
90 WriteFile(bw, filePath, m_files[filePath]);
91 }
92
93 //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks"); 108 //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks");
94 109
95 // Write two consecutive 0 blocks to end the archive 110 // Write two consecutive 0 blocks to end the archive
96 byte[] finalZeroPadding = new byte[1024]; 111 byte[] finalZeroPadding = new byte[1024];
97 bw.Write(finalZeroPadding); 112 m_bw.Write(finalZeroPadding);
98 113
99 bw.Flush(); 114 m_bw.Flush();
100 bw.Close(); 115 m_bw.Close();
101 } 116 }
102 117
103 public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding) 118 public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding)
@@ -119,39 +134,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
119 134
120 return oBytes; 135 return oBytes;
121 } 136 }
122
123 /// <summary>
124 /// Write a particular file of data
125 /// </summary>
126 /// <param name="filePath"></param>
127 /// <param name="data"></param>
128 protected void WriteFile(BinaryWriter bw, string filePath, byte[] data)
129 {
130 if (filePath.Length > 100)
131 WriteEntry(bw, "././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
132
133 char fileType;
134
135 if (filePath.EndsWith("/"))
136 {
137 fileType = '5';
138 }
139 else
140 {
141 fileType = '0';
142 }
143
144 WriteEntry(bw, filePath, data, fileType);
145 }
146 137
147 /// <summary> 138 /// <summary>
148 /// Write a particular file of data 139 /// Write a particular entry
149 /// </summary> 140 /// </summary>
150 /// <param name="bw"></param>
151 /// <param name="filePath"></param> 141 /// <param name="filePath"></param>
152 /// <param name="data"></param> 142 /// <param name="data"></param>
153 /// <param name="fileType"></param> 143 /// <param name="fileType"></param>
154 protected void WriteEntry(BinaryWriter bw, string filePath, byte[] data, char fileType) 144 protected void WriteEntry(string filePath, byte[] data, char fileType)
155 { 145 {
156 byte[] header = new byte[512]; 146 byte[] header = new byte[512];
157 147
@@ -208,10 +198,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
208 header[154] = 0; 198 header[154] = 0;
209 199
210 // Write out header 200 // Write out header
211 bw.Write(header); 201 m_bw.Write(header);
212 202
213 // Write out data 203 // Write out data
214 bw.Write(data); 204 m_bw.Write(data);
215 205
216 if (data.Length % 512 != 0) 206 if (data.Length % 512 != 0)
217 { 207 {
@@ -220,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
220 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired); 210 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired);
221 211
222 byte[] padding = new byte[paddingRequired]; 212 byte[] padding = new byte[paddingRequired];
223 bw.Write(padding); 213 m_bw.Write(padding);
224 } 214 }
225 } 215 }
226 } 216 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index e6146cf..d4c138a 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -173,9 +173,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
173 //log4net.Config.XmlConfigurator.Configure(); 173 //log4net.Config.XmlConfigurator.Configure();
174 174
175 MemoryStream archiveWriteStream = new MemoryStream(); 175 MemoryStream archiveWriteStream = new MemoryStream();
176 TarArchiveWriter tar = new TarArchiveWriter(); 176 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
177 177
178 tar.AddFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); 178 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
179 179
180 string part1Name = "object1"; 180 string part1Name = "object1";
181 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder(); 181 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
@@ -194,9 +194,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
194 part1Name, 194 part1Name,
195 Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z), 195 Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z),
196 part1.UUID); 196 part1.UUID);
197 tar.AddFile(ArchiveConstants.OBJECTS_PATH + object1FileName, object1.ToXmlString2()); 197 tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, object1.ToXmlString2());
198 198
199 tar.WriteTar(archiveWriteStream); 199 tar.Close();
200 200
201 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 201 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
202 202