SpringBoot large file uploads and Detailed code examples

To summarize large file fragmentation problem and resume broken uploads. Because the file is too large (such as 1G or more), you must consider the case of a network outage upload process. Network http request in itself already has a fragment upload function when the file transfer is relatively large, http protocols automatically moves the file sections (block), but this is not what we are talking about focus, we need to do is 1G ensure that part of the file after a network outage has been uploaded without having to retransmit the next time a network connection. So when we upload local, to large files to be fragmented, for example, is divided into 1024 * 1024B, is about large file into pieces 1M upload, server receives, and then combine these pieces into the original file, which is fragmented the basic principle. HTTP requires local upload to record the state of each piece, I tagged (wait loading finish) through three states, when network outages, connected again, upload from the breakpoint. Server by the file name, the total number of tablets to determine whether the file has finished uploading all.

        The following is the details:

  1, first get the file (audio and video, pictures)

Two cases, one is directly in the album library, one is calling camera. If it is to get (the details are not described in detail, a lot of the Internet) by UIImagePickerView, we will find that when you select a video, there will be compressed page of Figure 1, and finally we get the app is this video after compression video (not a video library of original video, there is a note that point, after you remember the operation of the compressed video release, the system will not help you release, you need to manually operate, we will discuss below), then by the UIImagePickerView protocol method - ( void ) :( imagePickerController the UIImagePickerController  *) :( Picker didFinishPickingMediaWithInfo NSDictionary  *) info info acquire video

fileInfo = {

    UIImagePickerControllerMediaType = "public.movie";

    UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/2AAE9E44-0E6D-4499-9AC3-93D44D8342EA/tmp/trim.F36EC46C-4219-43C8-96A7-FA7141AB64D2.MOV";

    UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=DEDA9406-3223-4F87-ABB2-98FB5F5EB9C4&ext=MOV";

}

UIImagePickerControllerMediaType is selected file types, such as KUTTypeImage, KUTTypeMovie. Here note the difference between movie and video, and there is a sound of video file, a video file is no sound, of course, is only Audio sound no video. UIImagePickerControllerMediaURL is the URL of the video (if a camera, then this is the original captured by video; if it is selected in the album library, video compression that is generated after). Notice that the URL does not point to an album library, through this URL you can operate the video such as delete, copy, etc., you can get the size of the compressed video. UIImagePickerControllerReferenceURL is a pointer to the album URL, the official explanation is that an NSURL all the information that references an asset in the AssetsLibrary framework , through this URL, you can get the video, including the file name, thumbnail, duration, etc. (by ALAssetsLibrary in the assetsLibrary assetForURL : referenceURL resultBlock :).

If a camera, pay attention to two Storage: Save pictures to the album assetsLibrary writeImageDataToSavedPhotosAlbum : UIImageJPEGRepresentation ([info valueForKey : UIImagePickerControllerOriginalImage], (CGFloat) 1.0 ) the Metadata : nil completionBlock : failureBlock:

Picture of high-fidelity compression method NSData * UIImageJPEGRepresentation (UIImage * image, CGFloat compressionQuality)

Video saved to the album: assetsLibrary  writeVideoAtPathToSavedPhotosAlbum: mediaUrl completionBlock: failureBlock:

 

Here, we get all the necessary documents and file information. The next thing is to file fragmentation.

 

2, the acquired file slices

First, I will get to such a file is saved in this class

@interface CNFile : NSObject

@property (nonatomic,copy)NSString* fileType;//image  or  movie

the @Property  ( nonatomic , Copy ) NSString * filePath; // file in the app path

the @Property  ( nonatomic , Copy ) NSString * fileName; // filename

the @Property  ( nonatomic , ASSIGN ) NSInteger  fileSize; // File Size

@Property (nonatomic, ASSIGN)  NSInteger  Trunks; // total number of sheets

@property (nonatomic,copy)NSString* fileInfo;

the @Property  ( nonatomic , strong ) UIImage * fileImage; // file thumbnails

@Property  ( nonatomic , strong ) NSMutableArray * fileArr; // tag upload status of each piece of

@end

So that we can operate up to every CNFile object.

 

-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{

  The method of obtaining the total number of sheets:

    int  offset = 1024 * 1024 ; (each of a size 1M)

    NSInteger chunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) + 1));

    NSLog(@"chunks = %ld",(long)chunks);

    The file fragmentation, data reads each one:

    NSData* data;

    NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:file.filePath];

    [readHandle seekToFileOffset:offset * chunk];

    data = [readHandle readDataOfLength:offset];

}

 

So that we get every piece of data to be uploaded, and then ask the server, whether the film already exists

(方法-(void)ifHaveData:(NSData*)data WithChunk:(NSInteger)chunk file:(CNFile*)file)

, If present, so chunk + 1, repeat the above method to read the next one, until the server is not present the sheet, the sheet is uploaded data. Note Setting upload status of the chunk of (wait loading finish) In this method, which will be related to local judges whether the file has finished uploading all.

 

The next step is the process of upload:

-(void)uploadData:(NSData*) data WithChunk:(NSInteger) chunk file:(CNFile*)file;

After a successful upload server returns the film, we have a lot to do:

1) first has been successfully uploaded the film's flag placed finish

[file.fileArr replaceObjectAtIndex:chunk withObject:@“finish"];

 

2) to see if all the pieces of the flag have been placed finish, if already finishi, stating that the file upload is complete, then delete the file, upload a file or the end of the next.

for (NSInteger j =0; j<chunks; j++){

if (j == chunks || ((j == chunks -1)&&([file.fileArr[j]isEqualToString:@"finish"])))

     [me deleteFile:file.filePath];

     [me readNextFile];

}

3) If you do not have finish, then look at the next chunk of the local flag with whether the wait

 NSLog (@ " view of % ld sheet state ", the chunk + . 1 );

 for(NSInteger i = chunk+1;i < chunks;i++)

  {

     NSString* flag = [file.fileArrobjectAtIndex:i];

      if ([flagisEqualToString:@"wait"]) {

             [me readDataWithChunk:ifileName:fileNamefile:file];

               break;

          }

   }

Between steps 2 and 3 may have a 2.5) determines whether the pause upload

if(me.isPause ==YES)

  {

  // the current read the first few pieces of several files saved locally

     [self saveProgressWithChunk:chunk file:file];

      return ;

   }

This operation is virtually the same as the upload process is interrupted network, in order to HTTP, the disconnection or pause, we want to present progress saved, skip to the next piece has been placed in front of the finish uploading.

And then there's a problem, if we just upload a piece of linear, in fact, lost the meaning of fragmentation uploaded, it should be combined with multi-threaded, so that part uploading process concurrently, simultaneously upload multiple pieces, thus improving the efficiency upload and make full use of network bandwidth.

    dispatch_async(dispatch_queue_t queue, ^{

        [me readDataWithChunk: chunk];

    })

Finally, note, each finished to upload a video, go see your app settings in the amount of storage space does not increase Oh, if you do not deal with the compressed video generation, you'll find the amount of space occupied by your app is very big.

Details refer to this article: http://blog.ncmem.com/wordpress/2019/08/12/%e5%a4%a7%e6%96%87%e4%bb%b6%e6%96%ad%e7 % 82% b9% e7% bb % ad% e4% bc% a0-2 /

Guess you like

Origin www.cnblogs.com/songsu/p/12540096.html