ChunkedUploadFileOperation.java 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* ownCloud Android client application
  2. * Copyright (C) 2012 Bartek Przybylski
  3. * Copyright (C) 2012-2013 ownCloud Inc.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2,
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. package com.owncloud.android.operations;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.io.RandomAccessFile;
  22. import java.nio.channels.FileChannel;
  23. import java.util.Random;
  24. import org.apache.commons.httpclient.HttpException;
  25. import org.apache.commons.httpclient.methods.PutMethod;
  26. import com.owncloud.android.datamodel.OCFile;
  27. import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer;
  28. import com.owncloud.android.oc_framework.network.webdav.ChunkFromFileChannelRequestEntity;
  29. import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
  30. import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
  31. import com.owncloud.android.utils.Log_OC;
  32. import android.accounts.Account;
  33. public class ChunkedUploadFileOperation extends UploadFileOperation {
  34. private static final long CHUNK_SIZE = 1024000;
  35. private static final String OC_CHUNKED_HEADER = "OC-Chunked";
  36. private static final String TAG = ChunkedUploadFileOperation.class.getSimpleName();
  37. public ChunkedUploadFileOperation( Account account,
  38. OCFile file,
  39. boolean isInstant,
  40. boolean forceOverwrite,
  41. int localBehaviour) {
  42. super(account, file, isInstant, forceOverwrite, localBehaviour);
  43. }
  44. @Override
  45. protected int uploadFile(WebdavClient client) throws HttpException, IOException {
  46. int status = -1;
  47. FileChannel channel = null;
  48. RandomAccessFile raf = null;
  49. try {
  50. File file = new File(getStoragePath());
  51. raf = new RandomAccessFile(file, "r");
  52. channel = raf.getChannel();
  53. mEntity = new ChunkFromFileChannelRequestEntity(channel, getMimeType(), CHUNK_SIZE, file);
  54. ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
  55. long offset = 0;
  56. String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(getRemotePath()) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
  57. long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
  58. for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
  59. if (mPutMethod != null) {
  60. mPutMethod.releaseConnection(); // let the connection available for other methods
  61. }
  62. mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
  63. mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
  64. ((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset);
  65. mPutMethod.setRequestEntity(mEntity);
  66. status = client.executeMethod(mPutMethod);
  67. client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
  68. Log_OC.d(TAG, "Upload of " + getStoragePath() + " to " + getRemotePath() + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
  69. if (!isSuccess(status))
  70. break;
  71. }
  72. } finally {
  73. if (channel != null)
  74. channel.close();
  75. if (raf != null)
  76. raf.close();
  77. if (mPutMethod != null)
  78. mPutMethod.releaseConnection(); // let the connection available for other methods
  79. }
  80. return status;
  81. }
  82. }