Open rainit2006 opened 7 years ago
写log到文件
StreamWriter writer = new StreamWriter(@"Log.txt", true);
writer.WriteLine("xxxxxx" + DateTime.Now.ToString("h:mm:ss tt"));
writer.Close();
或者写一个通用函数
private const string LOG_FILEPATH = @"xxxxxx\xxxxx.log";
public static void WriteCodeToLog(string logText)
{
try
{
StringBuilder dataPath = new StringBuilder();
dataPath.Append(GetPathById(xxxxGUIDxxxxx));
dataPath.Append(LOG_FILEPATH);
if (File.Exists(dataPath.ToString()) && !string.IsNullOrEmpty(logText))
{
using (StreamWriter sw = File.AppendText(dataPath.ToString()))
{
StringBuilder logBuffer = new StringBuilder();
logBuffer.AppendLine(
string.Format("[{0}]::{1}",
DateTime.Now,
logText));
sw.Write(logBuffer.ToString());
sw.Flush();
sw.Close();
}
}
}
catch
{
}
}
从Binary文件里1byte 单位地 读取数据
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <fstream>
using namespace std;
int main()
{
ifstream file("../TOKYO_PL_1-1000_2.ly5", std::ios_base::in | std::ios_base::binary);
if (!file.is_open())
{
cout << "Error opening file";
exit(1);
}
//unsigned char x;
char x;
int i = 0;
while (!file.eof() && (i < 20)) //本demo读取20个byte的数据
{
//file.seekg(sizeof(unsigned char)* i);
file >> x;
printf(", %#x, %#x\n", x, (unsigned char)x);
i++;
}
return 0;
}
这样读取binary文件有一个问题 : 0D(r)这样的文字会被视为换行符而不会被读取。 想解决这个问题,利用ifstream.get()函数。
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <fstream>
using namespace std;
int main()
{
ifstream file("../TOKYO_PL_1-1000_2.ly5", std::ios_base::in | std::ios_base::binary);
if (!file.is_open())
{
cout << "Error opening file";
exit(1);
}
char x;
int i = 0;
while (!file.eof() && (i < 20))
{
file.get(x);
printf(", %#x, %#x\n", x, (unsigned char)x); //char是有符号的,对于0xFx的文字会视为负数。
for (int j = 7; 0 <= j; j--)
printf("%d\n", (x >> j) & 0x01); //按bit显示。
i++;
}
return 0;
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
一行一行地读取文件
利用include
string x;
getline(file, x);
getting file names without extensions Path.GetFileNameWithoutExtension https://msdn.microsoft.com/ja-jp/library/system.io.path.getfilenamewithoutextension(v=vs.110).aspx Ex.
foreach (FileInfo fi in smFiles)
{
builder.Append(Path.GetFileNameWithoutExtension(fi.Name));
builder.Append(", ");
}
File writing operation File.AppendAllText 创建文件,并追加内容 File.WriteAllText 创建文件,覆盖写入内容
换行符: environment.NewLine
e.url.toString() + environment.NewLine
Which is fastest: read, fread, ifstream or mmap? https://lemire.me/blog/2012/06/26/which-is-fastest-read-fread-ifstream-or-mmap/
利用内存映射读取大文件 http://blog.csdn.net/kuaile123/article/details/11149751 内存映射的优势还是在于大文件。 fstream.open() 时,由于文件太大,IO一次读不了所有的数据,需要多次IO操作。 而内存映射,并不是将文件加载到内存。内存映射首先申请一段地址空间,并映射到物理存储器,而这里的物理存储器就是文件所在的磁盘,类似虚拟内存(pagefile); 当有需要时,程序不需要先把它加到内存,而是直接从磁盘读取。这样就减少了IO操作。
查找目录里的所有文件
下面例子是把目录下的文件列出来。
#include <windows.h>
void read_directory(const std::string& name, stringvec& v)
{
std::string pattern(name);
pattern.append("\\*");
WIN32_FIND_DATA data;
HANDLE hFind;
if ((hFind = FindFirstFile(pattern.c_str(), &data)) != INVALID_HANDLE_VALUE) {
do {
v.push_back(data.cFileName);
} while (FindNextFile(hFind, &data) != 0);
FindClose(hFind);
}
}
判断是文件还是目录 Call GetFileAttributes, and check for the FILE_ATTRIBUTE_DIRECTORY attribute.
BOOL isDirectory(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
GetFileAttributes API for C++ https://msdn.microsoft.com/en-us/library/aa364944(VS.85).aspx
如何让文件读取跳过某些行? 恐怕不能。
读取data block
std::fstream fin("filename.txt");
vector<char> buffer (1024,0); // create vector of 1024 chars with value 0
fin.read(&buffer[0], buffer.size());
https://stackoverflow.com/questions/12401183/c-reading-text-file-by-blocks
ifstream打开含中文路径名文件失败的原因 http://www.cnblogs.com/kevinGaoblog/archive/2012/07/20/2601236.html
在VS2008的“Property Pages”属性页中,选择“Configuration Properties”-->“General”,可以看到当前使用的字符集是“Multi-Byte Character Set”,也就是说程序中使用的是多字节字符集。 从设置选项中可以看到,工程中使用的字符集可设置为“Multi-Byte Character Set”或“Unicode Character Set”,其中“Multi-Byte Character Set”表示使用ANSI编码方式,“Unicode Character Set”表示使用UNICODE编码方式。
那么这两种编码方式有什么样的区别呢? (1)传统的计算机使用ANSI编码,在ANSI编码模式下,英文字符都用1个字节表示,而某些其它国家的文字(如汉字、日文),无法用单个字节来表示,ANSI便采用多个字节来表示这些字符(汉字是2个字节)。
(2)UNICODE包含UTF-8、UTF-16、UTF-32等多种编码方案(目前windows一般使用UTF-16)。拿UTF-16来说,规定所有字符都使用2个字节表示(不论英文字母还是汉字),对于超出2个字节范围的字符采用代理(采用4个字节表示)。 UNICODE相比ANSI有很多方面的优势(优势体现在哪?),微软非常提倡使用UNICODE编码方式,在MS较新版本的系统中都是采用UNICODE编码的。因此,即便我们在自己写的程序中使用了ANSI编码,系统会将其转换为UNICODE再对其进行处理。
接下来我们说一下ifstream。在调用ifstream的open方法时,系统内部调用mbstowcs_s进行文件名转换(mbstowcs_s函数的作用是把多字节字符转化为宽字符),需要注意的是,该函数的调用结果依赖于程序的本地化设置(什么是本地化设置?)。而本地化设置可以通过setlocale函数来设置,譬如:setlocale(LC_ALL, "chinese")表示将程序本身的语言设置为中文,而程序启动时默认设置为LC_ALL="C"。在使用mbstowcs_s进行字符串转换时,只有当LC_ALL="chinese"时,含中文的字符串才能正确的转换成其对应的宽字节字符,否则(在LC_ALL="C"时),汉字会被看成2个单字节的字符,然后再转换成宽字节的字符,这样转换的结果显然是错误的!这就是ifstream打开含中文路径的文件失败的原因,因为"d://测试.txt"转换后得到错误的路径,因此文件打不开!
解决方法如下:
/*方法1,
使用STL中的locale类的静态方法指定全局locale
使用该方法以后,cout可能不能正常输出中文,十分蹊跷
我发现了勉强解决的方法:不要在还原区域设定前用cout或wcout输出中文,
否则后果就是还原区域设定后无法使用cout wcout输出中文
*/
locale::global(locale(""));//将全局区域设为操作系统默认区域
file.open("d://测试//测试文本.txt");//可以顺利打开文件了
locale::global(locale("C"));//还原全局区域设定
cout<<file.rdbuf();
file.close();
/* 方法2,使用C函数setlocale,不能用cout输出中文的问题解决方法同上 */
setlocale(LC_ALL,"Chinese-simplified");//设置中文环境
file.open("c://测试//测试文本3.txt");//可以顺利打开文件了
setlocale(LC_ALL,"C");//还原
cout<<file.rdbuf();
file.close();
CFile类 GetLength(): 获得文件的大小。 比如文件内容需要占用内存228KB。
iRet = cFile.Open( (LPTSTR)filePath.GetBuffer(0) , CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone );
if ( iRet == 0 ) {
ASSERT(0);
vErrLogWrite( FATAL_ERROR , __FILE__ ,__LINE__,cString.GetBuffer(0),0,0);
return ERROR;
}
ulSize = (ulong)cFile.GetLength();
pcRetAddr = (char *)malloc( ulSize );
cFile.Read( pcAddr, ulSize );
cFile.Close();
fstream 是C++标准库提供的函数。但是它不能支持unicode。 也就是如果文件名或路径里包含unicode字符那么它的处理会失败。
fstream提供了三个类,用来实现c++对文件的操作。(文件的创建、读、写)。
文件打开模式: ios::in 读 ios::out 写 ios::app 从文件末尾开始写 ios::binary 二进制模式 ios::nocreate 打开一个文件时,如果文件不存在,不创建文件。 ios::noreplace 打开一个文件时,如果文件不存在,创建该文件 ios::trunc 打开一个文件,然后清空内容 ios::ate 打开一个文件时,将位置移动到文件尾
文件指针位置在c++中的用法: ios::beg 文件头 ios::end 文件尾 ios::cur 当前位置 例子:
常用的判断方法: good() 如果文件打开成功 bad() 打开文件时发生错误 eof() 到达文件尾
关于异常处理: In C++ iostreams do not throw exeptions by default. What you need is
关于close处理: ファイルストリームクラスの場合は、デストラクタが自動的に行ってくれます。 もし、明示的なクローズが必要であれば、closeメンバ関数を呼び出します。 ifs.close();