Reads the file from GCS in chunks and stores it in a tmp file, which is then passed to GcsWritableFile.
| 1065 | // Reads the file from GCS in chunks and stores it in a tmp file, |
| 1066 | // which is then passed to GcsWritableFile. |
| 1067 | Status GcsFileSystem::NewAppendableFile(const string& fname, |
| 1068 | std::unique_ptr<WritableFile>* result) { |
| 1069 | std::unique_ptr<RandomAccessFile> reader; |
| 1070 | TF_RETURN_IF_ERROR(NewRandomAccessFile(fname, &reader)); |
| 1071 | std::unique_ptr<char[]> buffer(new char[kReadAppendableFileBufferSize]); |
| 1072 | Status status; |
| 1073 | uint64 offset = 0; |
| 1074 | StringPiece read_chunk; |
| 1075 | |
| 1076 | // Read the file from GCS in chunks and save it to a tmp file. |
| 1077 | string old_content_filename; |
| 1078 | TF_RETURN_IF_ERROR(GetTmpFilename(&old_content_filename)); |
| 1079 | std::ofstream old_content(old_content_filename, std::ofstream::binary); |
| 1080 | while (true) { |
| 1081 | status = reader->Read(offset, kReadAppendableFileBufferSize, &read_chunk, |
| 1082 | buffer.get()); |
| 1083 | if (status.ok()) { |
| 1084 | old_content << read_chunk; |
| 1085 | offset += kReadAppendableFileBufferSize; |
| 1086 | } else if (status.code() == error::OUT_OF_RANGE) { |
| 1087 | // Expected, this means we reached EOF. |
| 1088 | old_content << read_chunk; |
| 1089 | break; |
| 1090 | } else { |
| 1091 | return status; |
| 1092 | } |
| 1093 | } |
| 1094 | old_content.close(); |
| 1095 | |
| 1096 | // Create a writable file and pass the old content to it. |
| 1097 | string bucket, object; |
| 1098 | TF_RETURN_IF_ERROR(ParseGcsPath(fname, false, &bucket, &object)); |
| 1099 | result->reset(new GcsWritableFile( |
| 1100 | bucket, object, this, old_content_filename, &timeouts_, |
| 1101 | [this, fname]() { ClearFileCaches(fname); }, retry_config_)); |
| 1102 | return Status::OK(); |
| 1103 | } |
| 1104 | |
| 1105 | Status GcsFileSystem::NewReadOnlyMemoryRegionFromFile( |
| 1106 | const string& fname, std::unique_ptr<ReadOnlyMemoryRegion>* result) { |