Java标准I/O流介绍
1、I/O是什么?
I/O 是Input/Output(输入、输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出。
2、流
流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据。流与数据源,或数据源流向的媒介相关联。
在Java IO流中,流可以是字节流,也可以是字符流。
3、Java I/O 用途与对应的流一览
注:粗体为节点流。蓝色为转换流(字节流转为字符流)。
4、流的处理
流分节点流和处理流两种。
节点流:可以从或向一个特定的地方(节点)读写数据。如FileInputStream、FileReader。
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接
5、文件访问
(1)读取文件
如果你需要在不同端使用读取文件,你可以根据你要读的文件是二进制文件还是文本文件,或者根据你要处理的数据是准备采取字节方式还是字符方式,决定使用 FileInputStream 或者 FileReader。两者支持你从文件开头开始到文件结尾读取一个字节或者字符,也可以将读取的多个字节或字符,写入到内存的字节数组或字符数组。
单字节读取文件示例:
public static void readFileAsByte() throws IOException {
String filepath = "file.bin";
java.io.InputStream is = null; try { is = new FileInputStream(filepath); int data = -1; while ((data = is.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((byte)data + " ");
}
} finally { if (is != null) { is.close();// 关闭流
}
}
}
字节数组读取文件示例:
public static void readFileAsByteArray() throws IOException {
String filepath = "file.bin";
java.io.InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(filepath));// 组装BufferedInputStream流,加入缓冲能力
byte[] data = new byte[256]; int len = -1; while ((len = is.read(data)) != -1) {// -1 表示读取到达文件结尾
//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i] + " ");
}
}
} finally { if (is != null) { is.close();// 关闭流
}
}
}
单字符读取文件示例:
public static void readFileAsChar() throws IOException {
String filepath = "file.txt";
java.io.Reader r = null; try {
r = new FileReader(filepath); int data = -1; while ((data = r.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((char) data);
}
} finally { if (r != null) {
r.close();// 关闭流
}
}
}
字符数组读取文件示例: public static void readFileAsCharArray() throws IOException {
String filepath = "file.txt";
java.io.Reader r = null; try {
r = new BufferedReader(new FileReader(filepath));// 组装BufferedReader流,加入缓冲能力
char[] data = new char[256]; int len = -1; while ((len = r.read(data)) != -1) {// -1 表示读取到达文件结尾
//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]);
}
}
} finally { if (r != null) {
r.close();// 关闭流
}
}
}
(2)写入文件 与读取文件类似: 如果你需要在不同端使用写入文件,你可以根据你要写的文件是二进制文件还是文本文件,或者根据你要处理的数据是准备采取字节方式还是字符方式,决定使用 FileOutputStream 或者 FileWriter。两者支持你可以一次写入一个字节或者字符到文件中,也可以直接写入一个字节数组或者字符数据。数据按照写入的顺序存储在文件当中。 单字节写入文件示例: public static void writeFileAsByte() throws IOException {
String filepath = "file.bin";
java.io.OutputStream os = null; try {
os = new FileOutputStream(filepath);
os.write('1');
os.write('2');
os.write('3');
os.write('4');
os.flush();// 把缓冲区内的数据刷新到磁盘 } finally { if (os != null) {
os.close();// 关闭流
}
}
}
字节数组写入文件示例: public static void writeFileAsByteArray() throws IOException {
String filepath = "file.bin";
java.io.OutputStream os = null; try {
os = new BufferedOutputStream(new FileOutputStream(filepath)); // 模拟
byte[] data = new byte[256]; new Random().nextBytes(data); os.write(data);
os.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (os != null) {
os.close();// 关闭流
}
}
}
单字符写入文件示例: public static void writeFileAsChar() throws IOException {
String filepath = "file.txt";
java.io.Writer w = null; try {
w = new FileWriter(filepath);
w.write('1');
w.write('2');
w.write('3');
w.write('4');
w.flush();// 把缓冲区内的数据刷新到磁盘 } finally { if (w != null) {
w.close();// 关闭流
}
}
}
字符数组写入文件示例: public static void writeFileAsCharArray() throws IOException {
String filepath = "file.txt";
java.io.Writer w = null; try {
w = new BufferedWriter(new FileWriter(filepath));// 组装BufferedWriter流,加入缓冲能力
// 模拟
char[] data = new char[256];
String f = "0123456789abcdefghijklmnopqrstuvwxyz";
Random rd = new Random(); for (int i = 0; i < data.length; i++) {
data[i] = f.charAt(rd.nextInt(f.length()));
}
w.write(data);
w.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (w != null) {
w.close();// 关闭流
}
}
}
(3)随机访问文件 如果你需要不按特定的存取顺序,随意读取或者写入文件,可以考虑RandomAccessFile。 void seek(long pos) 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 简单示例: public static void main(String[] args) throws IOException {
RandomAccessFile file = null; try { file = new java.io.RandomAccessFile("file.bin", "rw"); file.seek(0);
file.writeChar('1'); file.seek(0);
System.out.println(file.readChar());
/**
* 读取
*/
int data = -1; while ((data = file.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((byte)data + " ");
} } finally { if (file != null) { file.close();// 关闭流
}
}
} 6、管道(线程内存) 管道为同一JVM中运行的线程提供基于内存的通信机制。但是你不能利用管道在不同的JVM中的线程间通信。
在概念上,Java的管道不同于Unix/Linux系统中的管道。在Unix/Linux中,运行在不同地址空间的两个进程可以通过管道通信。在Java中,通信的双方应该是运行在同一进程中的不同线程。当然除了管道之外,一个JVM中不同线程之间还有许多通信的方式。实际上,线程在大多数情况下会传递完整的对象信息而非原始的字节数据。但是,如果你需要在线程之间传递字节数据,Java IO的管道是一个不错的选择。 当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。 简单示例: static class Input implements Runnable { private final PipedInputStream inputStream = new PipedInputStream(); public Input() {
} public PipedInputStream getInputStream() { return inputStream;
} @Override
public void run() { try { byte[] buf = new byte[1024]; int len = -1;
System.out.println("管道读取准备。");
StringBuffer result = new StringBuffer(); while ((len = inputStream.read(buf)) > 0) { //System.out.println(new String(buf, 0, len));
result.append(new String(buf, 0, len));
}
System.out.println("管道读取结果:" + result.toString());
} catch (IOException e) {
e.printStackTrace();
} finally { try { if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} static class Output implements Runnable { private final PipedOutputStream outputStream = new PipedOutputStream(); public Output() {
} public PipedOutputStream getOutputStream() { return outputStream;
} @Override
public void run() { try {
System.out.println("管道写出准备。");
StringBuilder sb = new StringBuilder(); // 模拟 通过for循环写入2050个字节
for (int i = 0; i < 201; i++) {
sb.append("0123456789"); if (i > 0 && (i % 10 == 0)) {
sb.append("\r\n");
}
}
String str = sb.toString();
outputStream.write(str.getBytes());
System.out.println("管道写出完成。");
} catch (IOException e) {
e.printStackTrace();
} finally { try { if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) throws IOException {
Input input = new Input();
Output output = new Output(); /**
* 将“管道输入流”和“管道输出流”关联起来。
*/
//input.getInputStream().connect(output.getOutputStream());// 与下面一行等价
output.getOutputStream().connect(input.getInputStream()); new Thread(input).start(); new Thread(output).start();
} 7、序列化与ObjectInputStream、ObjectOutputStream 使用ObjectInputStream、ObjectOutputStream读取或写入对象,首先该对象必须实现Serializable接口,使得能够序列化和反序列化。 简单示例: @SuppressWarnings("unused") public static void main(String[] args) throws IOException { class A implements java.io.Serializable { private static final long serialVersionUID = -9115696482036699559L; private int i = 1; private float f = 3; private String s = "风策信"; public A() { super();
} public A(int i, float f, String s) { super(); this.i = i; this.f = f; this.s = s;
} @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("A [i=").append(i).append(", f=").append(f).append(", s=").append(s).append("]"); return builder.toString();
}
} class B implements java.io.Serializable { private static final long serialVersionUID = 6124575321340728225L; private long i = 2; private double f = 4; private String str = "风策信"; public B() { super();
} public B(long i, double f, String str) { super(); this.i = i; this.f = f; this.str = str;
} @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("B [i=").append(i).append(", f=").append(f).append(", str=").append(str).append("]"); return builder.toString();
}
}
A a = new A(1, 3, "a");
B b = new B(2, 4, "b"); //System.out.println(a);
//System.out.println(b);
ObjectOutputStream oos = null; try {
oos = new ObjectOutputStream(new FileOutputStream("object.data.bin"));
oos.writeObject(a);
oos.writeObject(b);
oos.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (oos != null)
oos.close();
}
ObjectInputStream ois = null; try {
ois = new ObjectInputStream(new FileInputStream("object.data.bin"));
A a1 = (A) ois.readObject();
B b1 = (B) ois.readObject();
System.out.println(a1);
System.out.println(b1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally { if (ois != null)
ois.close();
}
} 8、回推流:PushbackInputStream与PushbackReader PushbackInputStream/PushbackReader 用于解析InputStream/Reader内的数据,允许你读取字节/字符后,回推(pushback)到流中,而不破坏流。 PushbackInputStream类具有以下构造函数: PushbackInputStream(InputStream inputStream)
PushbackInputStream(InputStream inputStream,int numBytes)
第一种形式创建的流对象允许将一个字节返回到输入流; 第二种形式创建的流对象具有一个长度为numBytes的回推缓存,从而允许将多个字节回推到输入流中。 提供了unread()方法,如下所示: void unread(int b)void unread(byte[] buffer)void unread(byte[] buffer,int offset,int numBytes)
第一种形式回推b的低字节,这会使得后续的read()调用会把这个字节再次读取出来。第二种形式回推buffer中的字节。第三种形式回推buffer中从offset开始的numBytes个字节。当回推缓存已满时,如果试图回推字节,就会抛出IOException异常。 示例: public static void main(String[] args) throws IOException {
String filepath = "file.bin";
java.io.OutputStream os = null; try {
os = new FileOutputStream(filepath);
os.write('#');
os.write(new byte[]{'a', 'b', 'c', 'd'});
os.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (os != null) {
os.close();// 关闭流
}
} /**
* 回推(pushback)
*/
PushbackInputStream pis = null; try { //pis = new PushbackInputStream(new FileInputStream(filepath));
pis = new PushbackInputStream(new FileInputStream(filepath), 3); int len = -1; byte[] bytes = new byte[2]; while ((len = pis.read(bytes)) != -1) { if ('b' == bytes[0]) { //pis.unread('U');
//pis.unread(bytes);
pis.unread(new byte[]{'1', '2', '3'});
} for (int i = 0; i < len; i++) {
System.out.print(((char) bytes[i]));
}
}
System.out.println();
} finally { if (pis != null)
pis.close();
} /**
* 会发现PushbackInputStream并没有改变目标介质的数据,不破坏流
*/
try {
pis = new PushbackInputStream(new FileInputStream(filepath)); int len = -1; byte[] bytes = new byte[2]; while ((len = pis.read(bytes)) != -1) { for (int i = 0; i < len; i++) {
System.out.print(((char) bytes[i]));
}
}
} finally { if (pis != null)
pis.close();
}
}
注:PushbackInputStream对象会使得InputStream对象(用于创建PushbackInputStream对象)的mark()或reset()方法无效。对于准备使用mark()或reset()方法的任何流来说,都应当使用markSupported()方法进行检查。 9、行数记录:LineNumberInputStream与LineNumberReader LineNumberInputStream与LineNumberReader提供跟踪行号的附加功能。行是以回车符 ('\r')、换行符 ('\n') 或回车符后面紧跟换行符结尾的字节序列。在所有这三种情况下,都以单个换行符形式返回行终止字符。 行号以 0 开头,并在 read 返回换行符时递增 1。 使用getLineNumber()可以获取当前读取所在行数。 示例: public static void main(String[] args) throws IOException {
String filepath = "file.txt";
java.io.Writer w = null; try {
w = new FileWriter(filepath);
w.write("百世山河任凋换,一生意气未改迁。愿从劫火投身去,重自寒灰飞赤鸾。\r\n");
w.write("沧海桑田新几度,月明还照旧容颜。琴心剑魄今何在,留见星虹贯九天。 \n");
w.write("冰轮腾转下西楼,永夜初晗凝碧天。长路寻仙三山外,道心自在红尘间。 \n");
w.write("何来慧剑破心茧,再把貂裘换酒钱。回望天涯携手处,踏歌重访白云间。\n");
w.write("何以飘零去,何以少团栾,何以别离久,何以不得安? \n");
w.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (w != null) {
w.close();// 关闭流
}
} /**
* LineNumberReader
*/
LineNumberReader lnr = null; try {
lnr = new LineNumberReader(new FileReader(filepath)); int len = -1; char[] chars = new char[2]; //int lastLineNumber = -1;
while ((len = lnr.read(chars)) != -1) { for (int i = 0; i < len; i++) {
System.out.print(((char) chars[i]));
} /*int lineNumber = lnr.getLineNumber();
if (lineNumber != lastLineNumber) {
System.out.println("---------------行数:" + lineNumber);
lastLineNumber = lineNumber;
}*/
} int lineNumber = lnr.getLineNumber();
System.out.println("行数:" + lineNumber);
System.out.println();
} finally { if (lnr != null)
lnr.close();
}
} 10、StreamTokenizer的使用 StreamTokenizer定义了几种基本的常量用于标识解析过程:TT_EOF(流结尾)、TT_EOL(行结尾)、TT_NUMBER(数字符号, 0 1 2 3 4 5 6 7 8 9 . -都属于数字语法)、TT_WORD(一个单词)。
ttype 在调用 nextToken 方法之后,此字段将包含刚读取的标记的类型。
nval 如果当前标记是一个数字,则此字段将包含该数字的值。
sval 如果当前标记是一个文字标记,则此字段包含一个给出该文字标记的字符的字符串。 public static void main(String[] args) throws IOException {
StreamTokenizer tokenizer = new StreamTokenizer(new StringReader("Sven had 7 shining ring...")); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {// 流末尾
if (tokenizer.ttype == StreamTokenizer.TT_WORD) {
System.out.println(tokenizer.sval);
} else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
System.out.println(tokenizer.nval);
} else if (tokenizer.ttype == StreamTokenizer.TT_EOL) {// 行末尾
System.out.println();
}
} //System.out.println(tokenizer.lineno());}
基本方法介绍一下: nextToken() - 从此标记生成器的输入流中解析下一个标记。 (1)标记注释 commenChar(int ch) - 指定某个字符为注释字符,此字符之后直到行结尾都被stream tokenizer忽略。 slashSlashComments(boolean flag) - 如果为true,则/*与*/之间的都被认为是注释,反之,不是。 slashStartComments(boolean flag) - 如果为true,则//之后到行结尾的所有都被认为是注释,反之,不是。 (2)基本语义 eolIsSignificant(boolean flag) - 决定一个行结束符是否被当作一个基本的符号处理,如果是true,则被当作一个基本符号,不当作普通的分隔符,如果是false,则保持原义,即当作普通的分隔符。 lowerCaseMode(boolean flag) - 决定是否读取一个单词时是否转变成小写。 parseNumbers() - 当stream tokenizer遭遇到一个单词为双精度的浮点数时,会把它当作一个数字,而不是一个单词。 resetSyntax() - 重置语法表使所有的字符都被认为是“ordinary”。 (3)指定字符语义 ordinaryChar(int ch) - 指定字符在这个tokenizer中保持原义,即只会把当前字符认为普通的字符,不会有其他的语义。
ordinaryChars(int low, int hi) - 指定范围内的字符保持语义,同上 whitespaceChars(int low, int hi) - 字符low与hi之间的所有字符都被当作为空格符,即被认识为tokenzier的分隔符。
wordChars(int low, int hi) - 字符low与hi之间的所有字符都被当作为单词的要素。一个单词是由一个单词要素后面跟着0个或者更多个单词要素或者数字要素。 11、合并流SequenceInputStream SequenceInputStream会将与之相连接的流集组合成一个输入流并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的末尾为止。 合并流的作用是将多个源合并合一个源。 public static void main(String[] args) throws IOException {
String filepath1 = "file1.txt";
String filepath2 = "file2.txt";
java.io.Writer w = null; try {
w = new FileWriter(filepath1);
w.write("百世山河任凋换,一生意气未改迁。愿从劫火投身去,重自寒灰飞赤鸾。\r\n");
w.write("沧海桑田新几度,月明还照旧容颜。琴心剑魄今何在,留见星虹贯九天。 \n");
w.write("冰轮腾转下西楼,永夜初晗凝碧天。长路寻仙三山外,道心自在红尘间。 \n");
w.write("何来慧剑破心茧,再把貂裘换酒钱。回望天涯携手处,踏歌重访白云间。\n");
w.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (w != null) {
w.close();// 关闭流
}
} try {
w = new FileWriter(filepath2);
w.write("何以飘零去,何以少团栾,何以别离久,何以不得安? ");
w.flush();// 把缓冲区内的数据刷新到磁盘
} finally { if (w != null) {
w.close();// 关闭流
}
}
java.io.Reader r = null; try {
Vector<InputStream> v = new Vector<InputStream>(2);
InputStream s1 = new FileInputStream(filepath1);
InputStream s2 = new FileInputStream(filepath2);
v.addElement(s1);
v.addElement(s2);
r = new BufferedReader(new InputStreamReader(new SequenceInputStream(v.elements())));
char[] data = new char[256]; int len = -1; while ((len = r.read(data)) != -1) {// -1 表示读取到达文件结尾
//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]);
}
}
} finally { if (r != null) {
r.close();// 关闭流
}
}
}
Java标准I/O流介绍的更多相关文章
- Java标准I/O流编程一览笔录
I/O是什么 I/O 是Input/Output(输入.输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出. 流 流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据.流与数据源,或 ...
- JAVA中的IO流介绍(2)
一.流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等. 一个流,必有源端和目的端, ...
- Java 标准 I/O 介绍
一.Java标准I/O知识体系图: 二.I/O是什么 I/O 是Input/Output(输入.输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出. 三.Java I/O 用途与对应的流一览 ...
- Java 标准 IO 流编程一览笔录( 上 )
Java标准I/O知识体系图: 1.I/O是什么? I/O 是Input/Output(输入.输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出. 2.流 流是一个连续的数据流,可以从流中读 ...
- Java中的IO流大体介绍
由于Java中的IO流是在是知识点繁多,所以我大约花了1周的时间将其整理起来.但是整理起来后并不是将完事了,我还是要分字节流和字符流来讲述.然后字节流和字符流中还有是否带有缓冲流. 讲述完IO流后我将 ...
- Java中的IO流系统详解(转载)
摘要: Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java ...
- Java 标准日志工具 Log4j 的使用(附源代码)
源代码下载 Log4j 是事实上的 Java 标准日志工具.会不会用 Log4j 在一定程度上可以说是衡量一个开发人员是否是一位合格的 Java 程序员的标准.如果你是一名 Java 程序员,如果你还 ...
- Java中的IO流系统详解
Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java 内用 U ...
- Web---JSTL(Java标准标签库)-Core核心标签库、I18N国际化、函数库
前面为JSTL中的常用EL函数,后面的为具体演示实例! JSTL简介: JSTL(Java Standard Tag Library) –Java标准标签库. SUN公司制定的一套标准标签库的规范. ...
随机推荐
- 找出此产品描述中包含N个关键字的长度最短的子串
阿里巴巴笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号:再给定N个英文关键词,请说明思路并变成实现方法. String extractSummary(Stri ...
- ionic2——开发利器之Visual Studio Code 常用插件整理
1.VsCode官方插件地址: http://code.visualstudio.com/docs 2.使用方法,可以在官网中搜索需要的插件或者在VsCode的“”扩展“”中搜索需要的插件 添加方法使 ...
- 【第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛-J】 强迫症的序列
小A是一个中度强迫症患者,每次做数组有关的题目都异常难受,他十分希望数组的每一个元素都一样大,这样子看起来才是最棒的,所以他决定通过一些操作把这个变成一个看起来不难受的数组,但他又想不要和之前的那个数 ...
- .net 学习路线感想(转)
从上到大学到现在工作,已经有六年多了,发现学习编程到以开发为工作也是一个挺长的过程的. 大学中,从c语言到java.C#到其他各种语言的学习,还有其他知识的学习如:数据库(oracle.sql Ser ...
- eclipse mars4.5安装hibernate开发环境
在安装hibernate插件过程中遇到下面前三张图片所示的现象是没关系的,只要最后能看到第四张图的结果就说明安装成功,我一开始不知道走了好多弯路.我用的eclipse mars4.5,采用了在线安装的 ...
- R+markdown+LaTeX 中文编译解决方案
一丢丢前言 很久之前曾试图以Rmarkdown编译pdf文档,无奈怎么鼓捣都会error,搜索了很久都没能找到比较好的解决方案.在配置上将编译器调成了xeLaTeX后就不了了之.这两天心血来潮研究了一 ...
- JavaScript碎片
option option 元素定义下拉列表中的一个选项(一个条目). 浏览器将 <option> 标签中的内容作为 <select> 标签的菜单或是滚动列表中的一个元素显示. ...
- (三十八)js之柯里化
先给大家介绍什么是柯里化与反柯里化 百度翻译: 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的 ...
- 【MFC】如何在MFC创建的程序中更改主窗口的属性 与 父窗口 WS_CLIPCHILDREN 样式 对子窗口刷新的影响 与 窗体区域绘制问题WS_CLIPCHILDREN与WS_CLIPSIBLINGS
如何在MFC创建的程序中更改主窗口的属性 摘自:http://blog.sina.com.cn/s/blog_4bebc4830100aq1m.html 在MFC创建的单文档界面中: (基于对话框的, ...
- 在linux中使用shell来分析统计日志中的信息
在运维工作中,要经常分析后台系统的日志,通过抓取日志中的关键字信息,对抓取结果进行统计,从而为监控结果提供基础数据.下面的shell演示了如何从大量的日志中取得想要的统计结果.其中展示了各种有趣的命令 ...