示例#1
0
        public void Write()
        {
            try
            {
                using (Stream objectsMS = GetTempStream())
                {
                    using (Stream metaMS = GetTempStream())
                    {
                        using (AssetsWriter writer = new AssetsWriter(objectsMS))
                        {
                            int ctr = 0;
                            foreach (var obj in Metadata.ObjectInfos)
                            {
                                ctr++;
                                var offset = (int)objectsMS.Position;
                                obj.GetObjectForWrite().Write(writer);
                                writer.Flush();
                                obj.DataOffset = offset;
                                var origSize = obj.DataSize;
                                obj.DataSize = (int)(objectsMS.Position - obj.DataOffset);
                                writer.AlignTo(8);
                            }
                        }
                        using (AssetsWriter writer = new AssetsWriter(metaMS))
                        {
                            Metadata.Write(writer);
                        }

                        Header.FileSize         = Header.HeaderSize + (int)objectsMS.Length + (int)metaMS.Length;
                        Header.ObjectDataOffset = Header.HeaderSize + (int)metaMS.Length;

                        int diff;
                        int alignment = 16; //or 32, I don't know which
                                            //data has to be at least 4096 inward from the start of the file
                        if (Header.ObjectDataOffset < 4096)
                        {
                            diff = 4096 - Header.ObjectDataOffset;
                        }
                        else
                        {
                            diff = alignment - (Header.ObjectDataOffset % alignment);
                            if (diff == alignment)
                            {
                                diff = 0;
                            }
                        }

                        if (diff > 0)
                        {
                            Header.ObjectDataOffset += diff;
                            Header.FileSize         += diff;
                        }

                        Header.MetadataSize = (int)metaMS.Length;
                        objectsMS.Seek(0, SeekOrigin.Begin);
                        metaMS.Seek(0, SeekOrigin.Begin);
                        lock (this)
                        {
                            try
                            {
                                CloseBaseStream();


                                FileProvider.DeleteFiles(AssetsRootPath.CombineFwdSlash(AssetsFilename + ".split*"));

                                using (Stream outputStream = GetTempStream())
                                {
                                    using (AssetsWriter writer = new AssetsWriter(outputStream))
                                    {
                                        Header.Write(writer);
                                    }
                                    metaMS.CopyTo(outputStream);


                                    if (diff > 0)
                                    {
                                        outputStream.Write(new byte[diff], 0, diff);
                                    }

                                    objectsMS.CopyTo(outputStream);

                                    outputStream.Seek(0, SeekOrigin.Begin);
                                    if (FileWasSplit)
                                    {
                                        int    splitCtr = 0;
                                        byte[] buffer   = new byte[1024 * 1024];
                                        do
                                        {
                                            Stream outFile = FileProvider.GetWriteStream($"{AssetsRootPath.CombineFwdSlash(AssetsFilename)}.split{splitCtr}");
                                            var    readLen = (int)(outputStream.Length - outputStream.Position);
                                            if (readLen < buffer.Length)
                                            {
                                                outputStream.Read(buffer, 0, readLen);
                                                outFile.Write(buffer, 0, readLen);
                                                break;
                                            }
                                            outputStream.Read(buffer, 0, buffer.Length);
                                            outFile.Write(buffer, 0, buffer.Length);
                                            splitCtr++;
                                        } while (true);
                                    }
                                    else
                                    {
                                        Stream writeStream = FileProvider.GetWriteStream(AssetsRootPath.CombineFwdSlash(AssetsFilename));
                                        outputStream.CopyTo(writeStream);
                                    }
                                }
                                FileProvider.Save();
                                _hasChanges = false;
                                foreach (var ptr in _knownPointers.Where(x => x.Owner.ObjectInfo.ParentFile == this && x.IsNew))
                                {
                                    ptr.IsNew = false;
                                }
                                OpenBaseStream();
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("CRITICAL: writing and reopening the file failed, the file is possibly destroyed and this object is in an unknown state.", ex);
                            }
                        }
                    }
                }
            }
            finally
            {
                CleanupTempFiles();
            }
        }
示例#2
0
        public void Write()
        {
            MemoryStream objectsMS = new MemoryStream();
            MemoryStream metaMS    = new MemoryStream();

            using (AssetsWriter writer = new AssetsWriter(objectsMS))
            {
                int ctr = 0;
                foreach (var obj in Metadata.ObjectInfos)
                {
                    ctr++;
                    obj.DataOffset = (int)objectsMS.Position;
                    obj.GetObjectForWrite().Write(writer);
                    writer.Flush();
                    var origSize = obj.DataSize;
                    obj.DataSize = (int)(objectsMS.Position - obj.DataOffset);
                    writer.AlignTo(8);
                }
            }
            using (AssetsWriter writer = new AssetsWriter(metaMS))
            {
                Metadata.Write(writer);
            }

            Header.FileSize         = Header.HeaderSize + (int)objectsMS.Length + (int)metaMS.Length;
            Header.ObjectDataOffset = Header.HeaderSize + (int)metaMS.Length;

            int diff;
            int alignment = 16; //or 32, I don't know which

            //data has to be at least 4096 inward from the start of the file
            if (Header.ObjectDataOffset < 4096)
            {
                diff = 4096 - Header.ObjectDataOffset;
            }
            else
            {
                diff = alignment - (Header.ObjectDataOffset % alignment);
                if (diff == alignment)
                {
                    diff = 0;
                }
            }

            if (diff > 0)
            {
                Header.ObjectDataOffset += diff;
                Header.FileSize         += diff;
            }

            Header.MetadataSize = (int)metaMS.Length;
            objectsMS.Seek(0, SeekOrigin.Begin);
            metaMS.Seek(0, SeekOrigin.Begin);
            try
            {
                CloseBaseStream();

                FileProvider.DeleteFiles(AssetsRootPath + AssetsFilename + ".split*");

                using (MemoryStream outputStream = new MemoryStream())
                {
                    using (AssetsWriter writer = new AssetsWriter(outputStream))
                    {
                        Header.Write(writer);
                    }
                    metaMS.CopyTo(outputStream);


                    if (diff > 0)
                    {
                        outputStream.Write(new byte[diff], 0, diff);
                    }

                    objectsMS.CopyTo(outputStream);

                    outputStream.Seek(0, SeekOrigin.Begin);
                    FileProvider.Write(AssetsRootPath + AssetsFilename, outputStream.ToArray(), true, true);
                }

                _hasChanges = false;
                FileProvider.Save();
                OpenBaseStream();
            }
            catch (Exception ex)
            {
                throw new Exception("CRITICAL: writing and reopening the file failed, the file is possibly destroyed and this object is in an unknown state.", ex);
            }
        }
示例#3
0
        public void Write(Stream outputStream)
        {
            MemoryStream objectsMS = new MemoryStream();
            MemoryStream metaMS    = new MemoryStream();

            using (AssetsWriter writer = new AssetsWriter(objectsMS))
            {
                int ctr = 0;
                foreach (var obj in Metadata.ObjectInfos.Select(x => x.Object))
                {
                    ctr++;
                    obj.ObjectInfo.DataOffset = (int)objectsMS.Position;
                    obj.Write(writer);
                    writer.Flush();
                    var origSize = obj.ObjectInfo.DataSize;
                    obj.ObjectInfo.DataSize = (int)(objectsMS.Position - obj.ObjectInfo.DataOffset);
                    writer.AlignTo(8);
                }
            }
            using (AssetsWriter writer = new AssetsWriter(metaMS))
            {
                Metadata.Write(writer);
            }

            Header.FileSize         = Header.HeaderSize + (int)objectsMS.Length + (int)metaMS.Length;
            Header.ObjectDataOffset = Header.HeaderSize + (int)metaMS.Length;

            int diff      = 0;
            int alignment = 16; //or 32, I don't know which

            //data has to be at least 4096 inward from the start of the file
            if (Header.ObjectDataOffset < 4096)
            {
                diff = 4096 - Header.ObjectDataOffset;
            }
            else
            {
                diff = alignment - (Header.ObjectDataOffset % alignment);
                if (diff == alignment)
                {
                    diff = 0;
                }
            }


            if (diff > 0)
            {
                Header.ObjectDataOffset += diff;
                Header.FileSize         += diff;
            }

            Header.MetadataSize = (int)metaMS.Length;
            objectsMS.Seek(0, SeekOrigin.Begin);
            metaMS.Seek(0, SeekOrigin.Begin);



            using (AssetsWriter writer = new AssetsWriter(outputStream))
            {
                Header.Write(writer);
            }
            metaMS.CopyTo(outputStream);


            if (diff > 0)
            {
                outputStream.Write(new byte[diff], 0, diff);
            }

            objectsMS.CopyTo(outputStream);
        }