C# FileStream read set encoding - c#

There might be something obvious I'm missing here, but I can't seem to set the encoding on my FileStream read. Here's the code:
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
using (fs)
{
byte[] buffer = new byte[chunk];
fs.Seek(chunk, SeekOrigin.Begin);
int bytesRead = fs.Read(buffer, 0, chunk);
while (bytesRead > 0)
{
ProcessChunk(buffer, bytesRead, database, id);
bytesRead = fs.Read(buffer, 0, chunk);
}
}
fs.Close();
Where ProcessChunk saves the read values to objects which are then serialized to XML, but the characters read appear wrong. The encoding needs to be 1250. I haven't seen an option to add the encoding to the FileStream. What am I missing here?

Rather than FileStream, use StreamReader. It has several constructors which allow you to specify the Encoding. For example:
StreamReader sr = new StreamReader(file, System.Text.Encoding.ASCII);
Since you require encoding 1250, this can be done with:
StreamReader sr = new StreamReader(file, System.Text.Encoding.GetEncoding(1250));
I would also suggest writing it as:
using (StreamReader sr = new StreamReader ...etc)
rather than declaring the variable outside the using; and you don't need to do the Close outside the using, since the Dispose will handle that.

You can also use both FileStream and FileReader :
using (FileStream fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding(1252)))
{
while (!sr.EndOfStream)
ProcessLine(sr.ReadLine());
}
}

Related

c# Two FileStreams write to text file but just one affect file

below code:
var fs = new FileStream(#"C:\Users\Michał\Desktop\tools\test.txt",
FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
var fs2 = new FileStream(#"C:\Users\Michał\Desktop\tools\test.txt",
FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
int a = 0;
while (a < 3)
{
byte[] info = new UTF8Encoding(true).GetBytes("DEF_");
byte[] info2 = new UTF8Encoding(true).GetBytes("abc_");
fs.Write(info, 0, info.Length);
Thread.Sleep(100);
fs2.Write(info2, 0, info2.Length);
Thread.Sleep(1000);
++a;
}
fs.Close();
fs2.Close();
Why result is that in a file there is just "abc_abc_abc" ?
FileShare.ReadWrite means for me other processes/threads can write to this file in the same time in FileStream ctor call.
You can achieve the desired behavior as follows:
using (var fs = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
using (var fs2 = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
byte[] info = new UTF8Encoding(true).GetBytes("DEF_");
byte[] info2 = new UTF8Encoding(true).GetBytes("abc_");
for (int i = 0; i < 3; i++)
{
fs.Seek(0, SeekOrigin.End);
fs.Write(info, 0, info.Length);
fs.Flush();
fs2.Seek(0, SeekOrigin.End);
fs2.Write(info2, 0, info2.Length);
fs2.Flush();
}
}
Before writing, each pointer of stream must be positioned at the end. This is done using the Seek method.
After writing, you need to flush the buffer to disk. This ensures that the stream is in the correct state before starting the next write. To do this, use the Flush method.
When you create a stream in its constructor, you can specify the FileOptions.WriteThrough. According to its description, the intermediate buffer should not be used. However, it still doesn't work without the Flush method. Perhaps experts will explain the reason.

Error "file in use" when playing aac while appending bytes to aac

var outputfile = "outputfile.aac";
var fileList = new List<string>
{
"1.aac",
"2.aac",
"3.aac",
"4.aac",
"5.aac",
"6.aac"
};
foreach (var file in fileList)
{
using (var stream = new FileStream(outputfile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
var bytes = File.ReadAllBytes(file);
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
}
}
I try to join aac files in fileList into outputfile. when writing file "3.aac" to outputfile.aac, I open outputfile with MediaPlayer, then the FileStream returns exception "file in use", even FileShare mode is ReadWrite, it means that other processes can read and write to the file. So where is the reason?
However, in this case output file is not blocked
Stream s = resp.GetResponseStream();
var fs = File.Exists(outputFile) ? new FileStream(outputFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)
: new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
byte[] buffer = new byte[4096];
while (s.CanRead)
{
int bytesRead = s.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, bytesRead);
}
P/s: I found that the reason because it's aac file
When you use FileShare.ReadWrite you allow subsequent opening of the file in read or write mode.
MediaPlayer then opens the file with FileShare.Read on its side, denying you write access to the file.

Writing a memory stream to a file

I have tried retrieving data in the json format as a string and writing it to a file and it worked great. Now I am trying to use MemoryStream to do the same thing but nothing gets written to a file - merely [{},{},{},{},{}] without any actual data.
My question is - how can I check if data indeed goes to memory stream correctly or if the problem occurs somewhere else. I do know that myList does contain data.
Here is my code:
MemoryStream ms = new MemoryStream();
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<myClass>));
dcjs.WriteObject(ms, myList);
using (FileStream fs = new FileStream(Path.Combine(Application.StartupPath,"MyFile.json"), FileMode.OpenOrCreate))
{
ms.Position = 0;
ms.Read(ms.ToArray(), 0, (int)ms.Length);
fs.Write(ms.ToArray(), 0, ms.ToArray().Length);
ms.Close();
fs.Flush();
fs.Close();
}
There is a very handy method, Stream.CopyTo(Stream).
using (MemoryStream ms = new MemoryStream())
{
StreamWriter writer = new StreamWriter(ms);
writer.WriteLine("asdasdasasdfasdasd");
writer.Flush();
//You have to rewind the MemoryStream before copying
ms.Seek(0, SeekOrigin.Begin);
using (FileStream fs = new FileStream("output.txt", FileMode.OpenOrCreate))
{
ms.CopyTo(fs);
fs.Flush();
}
}
Also, you don't have to close fs since it's in a using statement and will be disposed at the end.
using (var memoryStream = new MemoryStream())
{
...
var fileName = $"FileName.xlsx";
string tempFilePath = Path.Combine(Path.GetTempPath() + fileName );
using (var fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write))
{
memoryStream.WriteTo(fs);
}
}
//reset the position of the stream
ms.Position = 0;
//Then copy to filestream
ms.CopyTo(fileStream);
The issue is nothing to do with your file stream/ memory stream. The problem is that DataContractJsonSerializer is an OPT IN Serializer. You need to add [DataMemberAttribute] to all the properties that you need to serialize on myClass.
[DataContract]
public class myClass
{
[DataMember]
public string Foo { get; set; }
}
This line looks problematic:
ms.Read(ms.ToArray(), 0, (int)ms.Length);
You shouldn't need to read anything into the memory stream at this point, particularly when you're code is written to read ms into ms.
I'm pretty confident that simply removing this line will fix your problem.

Stream not readable

I'm sorry for not knowing a better way to subject this issue. I can modify once I better understand what is happening. I am trying to use a StreamWriter in the following code block:
public static bool SendFileToPrinter(string szPrinterName, string fontFileNames)
{
// Open the file.
FileStream fs = new FileStream(fontFileNames, FileMode.Open, FileAccess.Write);
//Add string to the file
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine ("Test");
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
When I add the stream writer I get a "Stream not readable" error and I'm not sure why. I'm new, so this is probably something elementary. I'm just trying to add a string to a file that I am sending to a printer (as raw PCL). Any help is appreciated.
You have some logical errors in your code:
You need to open your file as FileAccess.ReadWrite.
The FileMode.Open flag indicates that the operating system should open an existing file; however, you subsequently proceed to overwrite the first few bytes of its contents with your "Test" string. This is probably not desired behaviour. If you want to replace the file, use FileMode.Truncate. If you want to add your string to the end of the file, use FileMode.Append.
You need to flush the contents of your StreamWriter once you're done writing to it.
You need to reset your stream's position for your BinaryReader to read the written contents.
Don't forget to dispose your streams, readers, writers, and (preferably through using blocks).
Sample code:
// Open the file.
using (FileStream fs = new FileStream(fontFileNames, FileMode.Truncate, FileAccess.ReadWrite))
using (StreamWriter sw = new StreamWriter(fs))
{
//Add string to the file
sw.WriteLine("Test");
sw.Flush();
fs.Position = 0;
// Create a BinaryReader on the file.
using (BinaryReader br = new BinaryReader(fs))
{
/* rest of your code here */
}
}
Edit: Sample code with append:
// Open the file.
using (FileStream fs = new FileStream(fontFileNames, FileMode.Append, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs))
{
//Add string to the file
sw.WriteLine("Test");
}
// Create a BinaryReader on the file.
using (FileStream fs = new FileStream(fontFileNames, FileMode.Open, FileAccess.Read))
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((int)fs.Length);
/* rest of your code here */
}
The issue occurs because you open the FileStream with only write access:
FileStream fs = new FileStream(fontFileNames, FileMode.Open, FileAccess.Write);
and then try to read from it with BinaryReader:
bytes = br.ReadBytes(nLength);
Instead open the stream with read/write access:
... = new FileStream(fontFileNames, FileMode.Open, FileAccess.ReadWrite);

Uploading zip file with POST/httpwebrequest in C#

I'm trying code from http://www.paraesthesia.com/archive/2009/12/16/posting-multipartform-data-using-.net-webrequest.aspx to do a POST through httpwebrequest.
If I try this same code with a text file, it's fine. However if I do it with a zip file, then when re-download that file it's saying it's not a valid zip. I assume the zip portion is likely getting uploaded as text rather than binary. However, that page does say " It's OK to include binary content here. Don't base-64 encode it or anything, just stream it on in." But this doesn't seem to be working with the given code. I'm assuming I have to change the portion that reads the file to the stream:
using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
Maybe to use BinaryReader? I'm a bit confused on how to use that in this context though, or if it's even what I need to do. A nudge in the right direction would be awesome. Thanks!
BinaryReader should work indeed:
FileInfo fInfo = new FileInfo(file.FullName);
//
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
byte[] bdata = br.ReadBytes((int)numBytes);
br.Close();
fStream.Close();
// Write bdata to the HttpStream
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("url-here");
// Additional webRequest parameters settings.
HttpStream stream = (Stream)webRequest.GetRequestStream();
stream .Write(bdata, 0, bdata.Length);
stream.Close();
HttpWebResponse response = (HttpWebRewponse)webRequest.GetResponse();

Categories