I'm uploading a file that is a zip in a web app and passing it as type "Part" and I need to grab the name of the file that I originally uploaded. I can't seem to figure out for the life of me how to grab the actual name of the uploaded file. I've tried the following assuming my Part is uploaded with the original file name as "ABCD". My Part object will be named "file":
file.getHeaderNames() yields "content-type" and "content-disposition"
file.getName() yields "BPzip8237267963573706108tmp" which is the temp file's name
Any ideas on how I would go about doing this?
// define variable for file name
String filename = "";
// get part
Part file = request.getPart("file");
// get filename from part header
for (String s: file.getHeader("content-disposition").split(";")) {
if (s.trim().startsWith("filename")) {
filename = s.split("=")[1].replace("\"", "");
break;
}
}
Related
I have a custom form using a "managed_file" which uploads to temp folder. Programmatically, I then load that file and move it to its permanent storage (overwriting any existing file with the* name) e.g.
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
All of this works (i.e. the file physically is moved into the correct place with correct name); however, the file displayed in the listings (i.e. /admin/content/files) still shows the incorrect temporary folder as the URI.
Basically the file in the listings page seems to be showing the original filepath and name* of a previously successfully moved* file.
If I load this file with incorrect URI, i.e. using the incorrect temp path, the data loads, but then will not have a file info (as it doesn't exist. Also clicking the filename by browser under listings will show page not found and the URL showing the old URL i.e. /system/temporary?file=XYZ.pdf).
If I load this file by correct URI, i.e. using the correct destination path, file not found - same if I go to the path directly in the browser.
It appears the managed file doesn't know it was moved. How to resolve this bug?
The docs for FileSystem::move say "Moves a file to a new location without database changes or hook invocation."
So you are going to need to update the file entity with the new values..
Try this, untested:
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$newFileName = $this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
// Set the new file path on the file entity.
$upfile->setFileUri($newFileName);
// Set the file to permanent if needed.
$upfile->setPermanent();
// Save entity with changes.
$upfile->save();
I did not test this though.
You can check the functions on the file entity in the docs here
It turns out the class based methods do not update the database
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21FileSystem.php/function/FileSystem%3A%3Amove/8.9.x
The procedural version does
https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/file_move/8.9.x
Is there any way to open a file directly in browser instead of downloading it with the file name as it is?
window.open() -> opens file directly but it opens the file with a random numbered file name instead of the original file name.
Note : I know that download functionality can retain the original file name. But I need the same to work when the file directly opens without download.
This will work:
let newWindow = window.open('https://www.myetherwallet.com/img/big-spaceman.e9a9582b.png')
setTimeout(function () {
newWindow.document.title = "Spaceman";
}, 100);
}
I'm trying to use the code from this question getServingUrl() Method using Google Cloud Storage value
GcsFilename gcsFilename = new GcsFilename("bucketName", "objectName");
ImagesService is = ImagesServiceFactory.getImagesService();
String filename = String.format("/gs/%s/%s", gcsFilename.getBucketName(), gcsFilename.getObjectName());
String servingUrl = is.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(filename));
I don't understand why there is /gs/ in the beginning of the path - it causes the code to produce a url that doesn't exist. but when I remove it I get 'java.lang.IllegalArgumentException: Google storage filenames must be prefixed with /gs/'
So back to the original question - how to get a serving url from a GCS file?
I can do
"http://storage.googleapis.com/"+ filename.getBucketName()+"/"+ filename.getObjectName()
but it breaks on local server, thus I assume is not the correct way.
It depends on how you want to access the file. If you access the file directly from the client (browser), then you can use a public URL:
"http://storage.googleapis.com/"+ filename.getBucketName()+"/"+ filename.getObjectName()
If you access this file internally - in your code, or call getServingUrl(), you use "/gs/" prefix. For example:
Image picture = ImagesServiceFactory.makeImageFromFilename("/gs/" + filename.getBucketName() + "/" + filename.getObjectName());
GcsFilename fileName = new GcsFilename(filename.getBucketName(), filename.getObjectName());
I think there is just a problem with the file name in your example.
I have a public bucket here:
http://storage.googleapis.com/tripket1/
And all the files in this bucket have the ACL set to 'public-read'. Yet when I try to view any of the files, such as:
http://storage.googleapis.com/tripket1/2013-05-25%2019.17.32_150.jpg
it returns a 'NoSuchKey' error.
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
</Error>
What could be causing this problem? These files were uploaded using the GCS client library for Java. Here's a code snipped from the uploader:
GcsFilename thumbGcsFilename = new GcsFilename(bucketName, thumb_filename);
GcsFileOptions options = new GcsFileOptions.Builder().mimeType("image/" + photo_extension).acl("public-read").build();
GcsOutputChannel outputChannel = gcsService.createOrReplace(thumbGcsFilename, options);
outputChannel.write(ByteBuffer.wrap(newImageData));
outputChannel.close();
LOGGER.info("Wrote file");
String thumb_url_str = String.format("http://storage.googleapis.com/%s/%s", bucketName, thumb_filename);
return thumb_url_str;
You need to escape the % character in your object names.
For example, you have the following object:
gs://tripket1/2013-05-25%2019.17.32_150.jpg
Since you have a literal percent sign in your object's name, it must be escaped as %25 when URL encoded, so you can access the object with this URL:
http://storage.googleapis.com/tripket1/2013-05-25%252019.17.32_150.jpg
If you don't escape it, the %20 in your object name gets turned into a space () when being decoded at the server side, and it doesn't find an object name with a space in it.
Since it's a publicly readable bucket, I used gsutil to look at its contents, and I see the object you're trying to read is called
2013-05-25%2019.17.32_150.jpg
rather than
06b78005-4ad8-43d6-8fc5-bab867b653af/2013-05-25%2019.17.32_150.jpg
I have sucessfully managed to make a file upload system which basically is copying files to a specific folder and save in the database its location. Now i need help with the download part. Imagine my file location is: Files/1306242602661_file1.exe, and in my view i have this:
<g:link controller="fileManager" action="downloadFile">
Download</g:link><br>
I need help with the downloadFile controller. Could you please give me a hint about how to do this, considering my filename is a string:
String fileName = "Files/1306242602661_file1.exe"
Within your controller create an download action with following content:
def file = new File("path/to/file")
if (file.exists()) {
response.setContentType("application/octet-stream")
response.setHeader("Content-disposition", "filename=${file.name}")
response.outputStream << file.bytes
return
}
// else for err message
You can render a file. see http://grails.org/doc/2.4.x/ref/Controllers/render.html
render file: new File ("path/to/file.pdf"), fileName: 'myPdfFile.pdf'