Get file name from byte array or Stream
If the Stream
is actually a FileStream
, then this may be available by casting to FileStream
and accessing the .Name
property:
Stream stream = ...
FileStream fs = stream as FileStream;
if(fs != null) Console.WriteLine(fs.Name);
However, in the general case: no, this is not available. A byte[]
certainly has no concept of a filename, nor do most other types of streams. Likewise, a FileStream
base-stream that is being wrapped by other streams (compression, encryption, buffering, etc) will not expose such information, despite the underlying stream (several layers down) being a file.
I would handle the filename separately.
How to get a file name from a file's byte array?
The byte[]
that is returned by FileUtils.readFileToByteArray
is only the file contents, nothing else.
You should create your own class that is Serializable that includes two fields: a byte[]
for the file contents, and a java.io.File
that has everything else you need. You then serialize/deserialize your class into byte[]
, which is transmitted.
Get Filename from Byte Array
No. You can take a guess at a mimetype from the content data itself, but the filename is not in there.
Stream/Byte array to filename/extention/content type
If you know the extension, you can probably get the mime type from that. ASP.NET Core actually has something built in to the Static Files middleware that you can use:
var provider = new FileExtensionContentTypeProvider();
var contentType = provider.TryGetContentType(fileName, out var type)
? type
: "application/octet-stream";
return File(stream, contentType);
Other than that, Damien is correct in the comments, you cannot determine a mime type from byte data alone.
Changing the name of a file while in a filestream or byte array to send via WebAPI
The best way I could come up with was using my old method from years ago. The following shows how I used it. I only do this to mask the original filename from the third-party WebAPI I'm sending it to.
// filePath: c:\test\my_secret_filename.txt
private byte[] GetBytesWithNewFileName(string filePath)
{
byte[] file = null;
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// Change the name of the file in memory (does not affect the original file)
var fileNameField = fs.GetType().GetField(
"_fileName",
BindingFlags.Instance | BindingFlags.NonPublic
);
// If I leave out the next line, the file name field will have the full filePath
// string as its value in the resulting byte array. This will replace that with
// only the file name I wish to pass along "my_masked_filename.txt".
fileNameField.SetValue(fs, "my_masked_filename.txt");
// Get the filesize of the file and make sure it's compatible with
// the binaryreader object to be used
int fileSize;
try { fileSize = Convert.ToInt32(fs.Length); }
catch(OverflowException)
{ throw new Exception("The file is to big to convert using a binary reader."); }
// Get the file into a byte array
using (var br = new BinaryReader(fs)) { file = br.ReadBytes(fileSize); }
}
return file;
}
Display a file from a byte[] or stream
In windows, your only option is to do exactly what you're doing. Outlook, Internet explorer, firefox, all do this
Get the file postion of each file into a stream
What?This answer provides a 100% working example for:
- Serving multiple files as a single response from a web API using
multipart/mixed
content type, - Reading the file contents on the client by parsing the response of the web API implemented in 1
I hope this helps.
Server:
The server application is a .Net 4.7.2 MVC project with web API support.
The following method is implemented in an ApiController
and returns all the files under the ~/Uploads
folder in a single response.
Please make note of the use of Request.RegisterForDispose
extension to register the FileStream
s for later disposal.
public async Task<HttpResponseMessage> GetFiles()
{
string filesPath = System.Web.Hosting.HostingEnvironment.MapPath("~/Uploads");
List<string> fileNames = new List<string>(Directory.GetFiles(filesPath));
var content = new MultipartContent();
fileNames.ForEach(delegate(string fileName)
{
var fileContent = new StreamContent(File.OpenRead(fileName));
Request.RegisterForDispose(fileContent);
fileContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(fileContent);
});
var response = new HttpResponseMessage();
response.Content = content;
return response;
}
The response's Content-Type
header shows as Content-Type: multipart/mixed; boundary="7aeff3b4-2e97-41b2-b06f-29a8c23a7aa7"
and each file is packed in different blocks separated by the boundary
.
The client application is a .Net Core 3.0.1 console application.
Please note the synchronous usage of the async methods. This can be easily changed to asynchronous using await
, but implemented like this for simplicity:
using System;
using System.IO;
using System.Net.Http;
namespace console
{
class Program
{
static void Main(string[] args)
{
using (HttpClient httpClient = new HttpClient())
{
using (HttpResponseMessage httpResponseMessage = httpClient.GetAsync("http://localhost:60604/api/GetImage/GetFiles").Result)
{
var content = (HttpContent)new StreamContent(httpResponseMessage.Content.ReadAsStreamAsync().Result);
content.Headers.ContentType = httpResponseMessage.Content.Headers.ContentType;
MultipartMemoryStreamProvider multipartResponse = new MultipartMemoryStreamProvider();
content.ReadAsMultipartAsync(multipartResponse);
for(int i = 0; i< multipartResponse.Contents.Count;i++)
{
Stream contentStream = multipartResponse.Contents[i].ReadAsStreamAsync().Result;
Console.WriteLine("Content {0}, length {1}", i, contentStream.Length);
}
}
}
}
}
}
How to return byte array as an in memory file in java spring boot?
As a normal way I think it's better that you create a temp file in your web container and send it as a file to client. And also you can clean your temp files base on your policy with a schedule crontab. For more information please visit save temp file and clean temp
Related Topics
Lambda Where Id Does Not Exist in Another List
C# File.Delete, File Being Used by Another Process
How to Remove Windows Credentials
Controlling Datetime Parameter Formatting in Webapi 2
Sorting String Values Without Using Any Method/Function
How to Combine Values of Several Lists into One in C#
How to Delete Records Between Two Dates in Bulk
How to Set Autoincrement Ids in Unit Test
C# Best Way to Run a Function Every Second, Timer VS Thread
How to Ignore Convert to Nullable in Lambda Expressions
Load Image from Resources Area of Project in C#
Asp.Net Core Form Post Results in a Http 415 Unsupported Media Type Response
Getting the Latest File Modified from Azure Blob
How to Call Wcf Service Method from Postman
Ziparchive Gives Unexpected End of Data Corrupted Error
Asp.Net Core - Swashbuckle Not Creating Swagger.Json File
Get and Post Methods With the Same Action Name in the Same Controller