IO学习笔记整理

1. File类

1.1 File对象的三种创建方式:

File对象是一个抽象的概念,只有被创建出来之后,文件或文件夹才会真正存在

注意:File对象想要创建成功,它的目录必须存在!

import java.io.File;

/*
演示三种创建File对象的方式
*/
public class FileDemo {
public static void main(String[] args) throws Exception {
//指定完整路径名的字符串
File f1 = new File("e:/test/a.txt");
//指定父路径名以及子路径名的字符串
File f2 = new File("e:/test", "b.txt");
//指定父路径的File对象以及子路径名的字符串
File f3 = new File(new File("e:/test"), "c.txt"); f1.createNewFile();
f2.createNewFile();
f3.createNewFile(); }
}

如果使用的是相对路径(即不以盘符开头),那么默认的是当前项目的路径

1.2 mkdir和createNewFile方法

mkdir和createNewFile两个方法的区别,前者看成文件夹,哪怕写上了后缀,后者看成文件

import java.io.File;

/*
演示mkdir和createNewFile的区别
注:如果出现同名的文件以及文件夹,File会首先创建文件!
*/
public class FileDemo2 {
public static void main(String[] args) throws Exception {
File file1 = new File("e:/test/a.txt");
File file2 = new File("e:/test/aaa.txt");
//创建一个文本文件
file1.createNewFile();
//创建一个名为aaa.txt的文件夹
file2.mkdir();
}
}

在调用delete方法的时候要注意要删除的文件夹不能包含内容,否则就会报错

1.3 renameTo方法

renameTo方法如果在不同路径,就相当于剪切加重命名

import java.io.File;

/*
演示rename方法以及剪切的效果
*/
public class FileDemo3 {
public static void main(String[] args) {
File srcFile = new File("e:/test/a.txt");
File destFile = new File("e:/test/b.txt");
//如果源文件和目标文件拥有相同的父目录,那么就是改名操作
//srcFile.renameTo(destFile);
//如果两者的父目录不相同,那么就相当于剪切并改名
File destFile2 = new File("e:/test1/b.txt");
srcFile.renameTo(destFile2);
}
}

1.4 length方法的说明

关于length()方法,如果是文件的话返回文件的字节数,而如果是文件夹的话,是不确定的

import java.io.File;

/*
关于length方法的说明
*/
public class FileDemo4 {
public static void main(String[] args) {
//如果是一个文件的话,length方法即返回这个文件的字节数
File f1 = new File("e:/test/a.txt");
System.out.println(f1.length());
//如果是文件夹的话,返回值是不确定的,不一定是0,有时会是别的数字
File f2 = new File("e:/test");
System.out.println(f2.length());
}
}

1.5 listFiles方法

listFiles方法的优点是由于返回的是一个File类型的数组,而File本身有各种各样的方法,因此非常灵活,可以实现各种操作

import java.io.File;
import java.io.FilenameFilter; /*
演示listFiles方法,实现找到一个文件夹下一级子目录的所有txt文件,并把文件名打印出来
*/
public class FileDemo5 {
public static void main(String[] args) {
//常规方法
File f = new File("e:/test");
File[] files = f.listFiles();
for (File file : files) {
if(file.getName().endsWith(".txt")){
System.out.println(file.getName());
}
}
System.out.println("<---------------------->");
//使用FileNameFilter过滤出a.txt这个文件
//采用匿名内部类方式
File[] files1 = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return new File(dir,name).getName().equals("a.txt");
}
});
for (File file : files1) {
System.out.println(file.getName());
}
}
}

1.6 递归操作(查找以及删除)

递归地查找某一类文件

import java.io.File;

/*
演示递归地查找jpg文件并将文件名打印出来
*/
public class FileRecursiveDemo1 {
public static void main(String[] args) {
findJPG(new File("e:"));
}
public static void findJPG(File file){
File[] files = file.listFiles();
for (File f : files) {
if(f.isDirectory()){
findJPG(f);
}
else{
if(f != null && f.getName().toUpperCase().endsWith("JPG")){
System.out.println(f.getName());
}
}
}
}
}

递归删除文件夹

import java.io.File;

/*
演示递归删除文件夹以及文件夹下所有内容
*/
public class FileRecursiceDemo2 {
public static void main(String[] args) {
deleteDir(new File("e:/test"));
}
public static void deleteDir(File f){
File[] files = f.listFiles();
for (File file : files) {
if(file.isDirectory()){
deleteDir(file);
}else{
file.delete();
}
}
//文件都删除干净后,最后再把文件夹删除即可
f.delete();
}
}

2. 输入流和输出流

2.1 java IO框架中各种流的继承及实现图:

2.2 带异常处理的拷贝程序

基本思路:在try块中执行基本业务逻辑,catch中捕捉异常,记住使用Exception兜底,最后将关流操作放在finally中执行

import java.io.*;

/*
演示带完整异常处理的文件拷贝程序
*/
public class CopyFileDemo {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("e:/test/a.txt"));
bw = new BufferedWriter(new FileWriter("e:/test/b.txt"));
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
}
} catch (FileNotFoundException e) {
System.out.println("File Not Found !!!");
} catch (IOException e){
System.out.println("IO Exception !!!");
} catch (Exception e){
System.out.println("Unknown Exception !!!");
}finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
}
}
if(bw != null){
try {
bw.close();
} catch (IOException e) {
}
}
}
}
}

新版try-catch语句,可以将需要关闭的流使用try(){}形式放在小括号内,这样就不用再写finally块就能自动关流了

import java.io.*;

/*
演示带完整异常处理的文件拷贝程序升级版
*/
public class CopyFileDemo2 {
public static void main(String[] args) {
try (
BufferedReader br = new BufferedReader(new FileReader("e:/test/a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("e:/test/b.txt"));
){
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine(); }
} catch (FileNotFoundException e) {
System.out.println("File Not Found !!!");
} catch (IOException e){
System.out.println("IO Exception !!!");
} catch (Exception e){
System.out.println("Unknown Exception");
}
}
}

2.3 三种方式触发流的关闭

import java.io.BufferedOutputStream;
import java.io.FileOutputStream; /*
演示三种方式触发流的关闭
*/
public class StreamCloseDemo {
public static void main(String[] args) throws Exception {
//test1();
//test2();
test3();
} public static void test1() throws Exception {
//使用close方法关闭流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:/test/a.txt"));
bos.write("hello world".getBytes());
bos.close();
}
public static void test2() throws Exception{
//手动刷新
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:/test/a.txt"));
bos.write("hello world".getBytes());
bos.flush();
}
public static void test3() throws Exception{
//当写出的字节数大于等于8192的时候,就会自动触发关流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:/test/a.txt"));
bos.write(new byte[8192]);
}
}

对于第三种方式,对比图如下:

当写出的字节数为8191的时候,文件字节大小为0字节,说明并未关流

而当写出字节数为8192的时候,文件字节正好为8KB,说明写出成功!

2.4 数据流

由于后期在用到hadoop中的时候会涉及到ComparableWritable接口的重写方面的知识,因此这里需要关注,特别关注writeInt方法的底层实现!可以查看这些方法的底层源码!

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream; /*
演示数据流的基本方法:
1.数据流具有丰富的API可以读写各种各样的数据类型而不用每次都调用getBytes()方法
2.注意,若用数据流将数据写出到文本文件,则会出现乱码,解决方案是再用read方法读回来
*/
public class DataInputOutputStreamDemo {
public static void main(String[] args) throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("e:/test/a.txt"));
dos.writeBoolean(true);
dos.writeByte(97);
dos.writeChar('b');
dos.writeInt(10);
dos.writeDouble(3.14);
dos.writeUTF("hello world");
//然后用相对应的方法读回来
DataInputStream dis = new DataInputStream(new FileInputStream("e:/test/a.txt"));
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
}
}

WriteInt和ReadInt的源码分析:

  // writeInt
    public final void writeInt(int v) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(4);
}

查看了writeInt方法的实现原理,可知,它底层是通过将一个int类型的数据通过无符号右移操作从高位到低位一个一个拿出8位来实现的,而与0xFF进行与运算则保证了,除了这8位,其他位全部都是0,而readInt()方法则正好相反,将所有的获得的4个数字再进行左移操作,再加到一起去即可,具体代码如下:

public final int readInt() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}

知道了底层原理之后,自己也可以写字节数组和int值相互转换的方法:

/*
写两个将字节数组与int值相互转换的方法
*/
public class MyUtils { public static void main(String[] args) {
//进行测试
int b = -256;
byte[] bytes = int2Bytes(b);
System.out.println(bytes2Int(bytes));
} public static byte[] int2Bytes(int i){
byte[] bytes = new byte[4];
bytes[0] = (byte) (i >> 24);
bytes[1] = (byte) (i >> 16);
bytes[2] = (byte) (i >> 8);
bytes[3] = (byte) (i >> 0);
return bytes;
} public static int bytes2Int(byte[] bytes){
int i1 = bytes[0] & 0xFF << 24;
int i2 = bytes[1] & 0xFF << 16;
int i3 = bytes[2] & 0xFF << 8;
int i4 = bytes[3] & 0xFF << 0;
return i1 + i2 + i3 + i4;
}
}

2.5 打印流

打印流是单向的,只有输出方法,没有读取方法,但是有其特殊的打印方法,并且经过设置可以实现自动关流

import java.io.FileOutputStream;
import java.io.PrintWriter; /*
演示打印流的基本操作
*/
public class PrintWriterDemo {
public static void main(String[] args) throws Exception {
//设置成可以自动关流的那种,根据文档可知,自动关流只对println等方法有效
PrintWriter pw = new PrintWriter(new FileOutputStream("e:/test/a.txt"),true);
//使用自带的特殊方法
pw.println(10);
pw.println(3.14);
pw.println("hello world");
}
}

2.6 内存流

本质上不涉及到文件的IO,是用数组来实现的,写的时候会写出到一个无名的数组,当调用toByteArray方法时可以返回字节数组

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; /*
演示内存流的基本方法
*/
public class ByteArrayInputOutputStreamDemo {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("hello world".getBytes());
byte[] bytes = baos.toByteArray();
System.out.println(new String(bytes));
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
int len = 0;
byte[] buf = new byte[1024];
len = bais.read(buf);
System.out.println(new String(buf,0,len)); }
}

2.7 RandomAccessFile(随机访问文件)

import java.io.RandomAccessFile;

/*
演示随机访问文件类:
1.该类相当于是一个巨大的byte数组,即可以读文件又可以写文件
2.具有seek方法可以随便移动指针
3.有只读模式以及正常模式
*/
public class RandomAccessFileDemo {
public static void main(String[] args) throws Exception {
//指定的模式使得它既可以读,又可以写
RandomAccessFile raf = new RandomAccessFile("e:/test/a.txt", "rw");
raf.writeByte(98);
raf.writeLong(100L);
raf.writeUTF("hello world");
//试验:将指针移动至第9个字节处,查看是否可以读到hello world字符串
raf.seek(9L);
System.out.println(raf.readUTF());
}
}

2.8 Properties类(配置文件)

此类并不是IO,但是和IO关系很紧密,查看源码可知它是继承自HashTable的,因此可以把它当成map使用

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties; /*
演示一个简单的配置文件的读取以及更新等操作
*/
public class PropertiesDemo {
public static void main(String[] args) throws Exception {
//先用一个输入流读取已经存在了的配置文件
FileInputStream fis = new FileInputStream("e:/test/prop.txt");
Properties prop = new Properties();
prop.load(fis);
System.out.println(prop.getProperty("name"));
//进行更新操作,如果不存在,那就是添加
prop.setProperty("id","0001");
//更新的内容还是输出到原来文件中去
//如果不想写上comments的话,可以写null,但是绝对不可以出现中文,否则就会出现乱码
prop.store(new FileOutputStream("e:/test/prop.txt"),null);
}
}

2.9 对象输出 / 输入流 (ObjectOutputStream / ObjectInputStream)

对象输出流使得对象,这样一个具有立体结构类型的数据能够永久化地保存在磁盘上去,(这一过程就叫做持久化,在之后的大数据学习过程中会反复接触到),这样就使得对象可以脱离程序而存在,该过程就叫做“序列化”,而"反序列化“则正好相反,将一个已经保存在磁盘上的对象再反过来读到内存中

想要序列化一个对象,必须具备这样一个前提,那就是该对象要实现Serializable接口,该接口十分特殊,方法体内没有任何代码,是一个标记性接口,相当于在告诉用户,如果对象要想序列化,就得实现这个接口,不实现它,那就不能用!

public interface Serializable {
}

判断末尾的方法:之前的都要一个结束符,-1或是null,而Object却没有,因此,判断结束条件的方法不一样

需要注意的是:对象流和之前接触到的流判断是否达到文件末尾的方法不一样,由于对象流在写出到文件时,并不会在末尾添加-1或null这样的结束符,因此通过原来的方式判断是否达到文件末尾将不再适用,会抛出EOFException,解决方案是将所有的对象全部放在一个集合中,在反序列化时一次性读取整个集合即可,演示代码如下所示:

/*
演示对象流
演示解决EOFException的方案
*/ import java.io.*;
import java.util.ArrayList; class Employee implements Serializable {
private int id;
private String name; public Employee() {
} public Employee(int id, String name) {
this.id = id;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
} public class ObjectStreamDemo {
public static void main(String[] args) throws Exception {
//serialize();
deSerialize();
}
//序列化方法
public static void serialize() throws Exception {
//创建100个员工对象将它们放到集合中并持久化保存起来
ArrayList<Object> list = new ArrayList<>();
for(int i = 1; i <= 100; i++){
Employee emp = new Employee();
emp.setId(i);
emp.setName("tom" + i);
list.add(emp);
}
//对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/test/oos.txt"));
//使用该输出流特有的方法writeObject()
oos.writeObject(list);
oos.close();
}
//反序列化方法
public static void deSerialize() throws Exception{
//一次性读取一整个集合,这样就避免了EOFException异常的问题
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/test/oos.txt"));
Object obj = ois.readObject();
ArrayList<Object> list = (ArrayList<Object>) obj;
for (Object o : list) {
System.out.println((Employee) o);
}
}
}

3. IO的应用

3.1 切割小文件 & 合并小文件

  /**
* 给定需要进行切割的大文件的文件路径,需要存放小文件的目标文件夹,以及每个小文件的大小
*
* @param srcFilePath 源文件的路径
* @param destDir 目标文件夹
* @param size 每个小文件的大小
*/
public static void splitFile(String srcFilePath, String destDir, long size){
//先进行判断,只有源文件的大小大于等于小文件大小时,才进行切割
File srcFile = new File(srcFilePath);
long srcFileLen = srcFile.length();
if(srcFileLen < size){
System.out.println("Small file's size is larger than source file's size!");
}else{
//判断能够把文件切割成几份
int count = (int) (srcFileLen % size == 0 ? srcFileLen / size : srcFileLen / size + 1);
//遍历count变量,如果是最后一个小文件的话,重新计算文件长度
long len = size;
for(int i = 0; i < count; i++){
if(srcFileLen % size != 0 && i == count - 1){
len = srcFileLen % size;
}
copyFile(srcFile,destDir,i,i * size,len);
}
}
} /**
* 将切割好的文件进行合并,合并到另一个目录下
*
* @param srcDir 源文件夹
* @param destDir 目标文件夹
*/
public static void mergeFile(String srcFilePath, String srcDir, String destDir){
String srcFileName = new File(srcFilePath).getName();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(destDir,srcFileName));
File[] files = new File(srcDir).listFiles();
for (File file : files) {
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024 * 8];
int len = 0;
while((len = fis.read(buf)) != -1){
fos.write(buf,0,len);
}
fis.close();
} } catch (FileNotFoundException e) {
System.out.println("File Not Found!");
} catch (Exception e){
System.out.println("Unknown Exception!");
} finally {
if(fos != null){
try {
fos.close();
} catch (IOException e) {
}
}
}
} /**
*
* 单独将拷贝文件方法抽取出来
*
* @param srcFile 源文件
* @param destDir 目标文件夹
* @param i 小文件索引
* @param offset 被切割文件的偏移量,即从哪个字节开始切割
* @param len 需要拷贝的小文件的长度
*/
public static void copyFile(File srcFile, String destDir, int i, long offset, long len){
RandomAccessFile raf = null;
FileOutputStream fos = null;
try {
raf = new RandomAccessFile(srcFile,"rw");
raf.seek(offset);
byte[] buf = new byte[(int) len];
//一次性把数组读满
raf.read(buf);
fos = new FileOutputStream(new File(destDir, srcFile.getName() + "_" + i));
fos.write(buf); } catch (FileNotFoundException e) {
System.out.println("File Not Found!");
} catch (Exception e){
System.out.println("Unknown Exception!");
} finally {
if(raf != null){
try {
raf.close();
} catch (IOException e) {
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
}
}
}
}
}

3.2 归档文件 & 解档文件

简单说明:文件归档过后若想要解档,则必须要知道文件名是什么,以及文件长度是多少,因此,在进行归档操作时,必须写入这些控制字符,然后在解档时先对这些控制字符进行解析,解析完之后才能真正地进行文件的写出

/**
* 指定源文件夹,将文件夹下的所有文件夹归档至目标文件夹去
*
* @param srcDir 源文件夹
* @param destDir 目标文件夹
*/
public static void archiveFile(String srcDir, String destDir){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(destDir, "archive.dat"));
//列出这个文件夹下的文件
File[] files = new File(srcDir).listFiles();
for (File file : files) {
if(file.isFile()){
//先写文件名的长度,一个字节存放足够
int fileNameLen = file.getName().length();
fos.write(fileNameLen);
//然后写真实的文件名
fos.write(file.getName().getBytes());
//写四个字节的文件内容长度,自己手写一个工具类
fos.write(int2Bytes((int) file.length()));
//开始正式拷贝真实的文件
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024 * 8];
int len = 0;
while((len = fis.read(buf)) != -1){
fos.write(buf,0,len);
}
fis.close();
}
}
} catch (FileNotFoundException e) {
System.out.println("File Not Found!");
} catch (Exception e){
System.out.println("Unknown Exception!");
} finally {
//关闭资源
if(fos != null){
try {
fos.close();
} catch (IOException e) {
}
}
}
} /**
* 将归好档的文件进行解档操作至目标文件夹中去
*
* @param srcDir 已经归好档的文件所在的文件夹
* @param destDir 需要解档到的目标文件夹
*
*/
public static void unarchiveFile(String srcDir, String destDir) {
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(srcDir,"archive.dat"));
//先用read方法读一个字节读出文件名长度的字节
int b = 0;
while((b = fis.read()) != -1){
byte[] fileNameBytes = new byte[b];
//读取b长度字节数的文件名数组
fis.read(fileNameBytes);
//解析出文件名
String fileName = new String(fileNameBytes);
//读取4个字节的byte数组并将其还原回int值表示文件的真实长度
byte[] fileLenBytes = new byte[4];
fis.read(fileLenBytes);
int fileLen = bytes2Int(fileLenBytes);
//读取fileLen长度的文件真实数据
byte[] fileBytes = new byte[fileLen];
fis.read(fileBytes);
FileOutputStream fos = new FileOutputStream(new File(destDir, fileName));
fos.write(fileBytes);
fos.close();
}
} catch (FileNotFoundException e) {
//System.out.println("File Not Found!");
} catch (Exception e){
System.out.println("Unknown Exception!");
} finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
}
}
}
} /**
* 将一个整型数转换成字节数组
*
* @param i 传入的int值
*/
public static byte[] int2Bytes(int i){
byte[] bytes = new byte[4];
bytes[0] = (byte) (i >> 24);
bytes[1] = (byte) (i >> 16);
bytes[2] = (byte) (i >> 8);
bytes[3] = (byte) (i >> 0);
return bytes;
} /**
* 将一个字节数组还原成int值
*
* @param bytes 长度为4的字节数组
*
*/
public static int bytes2Int(byte[] bytes){
int i1 = (bytes[0] & 255) << 24;
int i2 = (bytes[1] & 255) << 16;
int i3 = (bytes[2] & 255) << 8;
int i4 = (bytes[3] & 255) << 0;
return i1 + i2 + i3 + i4;
}

大数据学习笔记——Java篇之IO的更多相关文章

  1. 大数据学习笔记——Java篇之集合框架(ArrayList)

    Java集合框架学习笔记 1. Java集合框架中各接口或子类的继承以及实现关系图: 2. 数组和集合类的区别整理: 数组: 1. 长度是固定的 2. 既可以存放基本数据类型又可以存放引用数据类型 3 ...

  2. 大数据学习笔记——Java篇之网络编程基础

    Java网络编程学习笔记 1. 网络编程基础知识 1.1 网络分层图 网络分层分为两种模型:OSI模型以及TCP/IP网络模型,前者模型分为7层,是一个理论的,参考的模型:后者为实际应用的模型,具体对 ...

  3. 大数据学习笔记——Java篇之基础知识

    Java / 计算机基础知识整理 在进行知识梳理同时也是个人的第一篇技术博客之前,首先祝贺一下,经历了一年左右的学习,从完完全全的计算机小白,现在终于可以做一些产出了!可以说也是颇为感慨,个人认为,学 ...

  4. 大数据学习笔记——Linux完整部署篇(实操部分)

    Linux环境搭建完整操作流程(包含mysql的安装步骤) 从现在开始,就正式进入到大数据学习的前置工作了,即Linux的学习以及安装,作为运行大数据框架的基础环境,Linux操作系统的重要性自然不言 ...

  5. 大数据学习笔记——Hadoop编程实战之HDFS

    HDFS基本API的应用(包含IDEA的基本设置) 在上一篇博客中,本人详细地整理了如何从0搭建一个HA模式下的分布式Hadoop平台,那么,在上一篇的基础上,我们终于可以进行编程实操了,同样,在编程 ...

  6. 大数据学习笔记之Hadoop(一):Hadoop入门

    文章目录 大数据概论 一.大数据概念 二.大数据的特点 三.大数据能干啥? 四.大数据发展前景 五.企业数据部的业务流程分析 六.企业数据部的一般组织结构 Hadoop(入门) 一 从Hadoop框架 ...

  7. 大数据学习笔记——Hadoop编程实战之Mapreduce

    Hadoop编程实战——Mapreduce基本功能实现 此篇博客承接上一篇总结的HDFS编程实战,将会详细地对mapreduce的各种数据分析功能进行一个整理,由于实际工作中并不会过多地涉及原理,因此 ...

  8. 大数据学习笔记——Linux基本知识及指令(理论部分)

    Linux学习笔记整理 上一篇博客中,我们详细地整理了如何从0部署一套Linux操作系统,那么这一篇就承接上篇文章,我们仔细地把Linux的一些基础知识以及常用指令(包括一小部分高级命令)做一个梳理, ...

  9. 大数据学习笔记——HBase使用bulkload导入数据

    HBase使用bulkload批量导入数据 HBase可使用put命令向一张已经建好了的表中插入数据,然而,当遇到数据量非常大的情况,一条一条的进行插入效率将会大大降低,因此本篇博客将会整理提高批量导 ...

随机推荐

  1. lqb 入门训练 序列求和 (PS:用长整数做数据的输入输出)

    入门训练 序列求和 时间限制:1.0s   内存限制:256.0MB     问题描述 求1+2+3+...+n的值. 输入格式 输入包括一个整数n. 输出格式 输出一行,包括一个整数,表示1+2+3 ...

  2. go中的关键字-defer

    1. defer的使用 defer 延迟调用.我们先来看一下,有defer关键字的代码执行顺序: func main() { defer func() { fmt.Println("1号输出 ...

  3. python脚本编写(纯干货)

    写博客的经验不是很多,写的不好或者有什么建议请留言或者联系作者 文章所有权归作者所有,转载转发请联系作者,侵权必纠. 废话不多说,直接开始吧! python脚本的作用也就不说了,首先是一个reques ...

  4. 全栈项目|小书架|微信小程序-登录及token鉴权

    小程序登录 之前也写过微信小程序登录的相关文章: 微信小程序~新版授权用户登录例子 微信小程序-携带Token无感知登录的网络请求方案 微信小程序开通云开发并利用云函数获取Openid 也可以通过官方 ...

  5. webpack-dev-middleware 和 webpack-hot-middleware 配置开发环境和生产环境;webpack脚手架;仿vue-cli

    webpack-dev-server更新后自带express服务器,已经不需要自己搭建.vue-cli从17年底左右也换成了最新的webpack-dev-server,而不是用webpack-dev- ...

  6. 2019-11-24:postgresql数据库安装,最后报错failed to load SQLModule 问题的解决方案

    安装环境:Windows 10 问题描述:Failed to load sql modules into the database cluster 原因在于 Postgresql 没有安装完全. 解决 ...

  7. Spring Boot2 系列教程(二十七)Nginx 极简扫盲入门

    上篇文章和大家聊了 Spring Session 实现 Session 共享的问题,有的小伙伴看了后表示对 Nginx 还是很懵,因此有了这篇文章,算是一个 Nginx 扫盲入门吧! 基本介绍 Ngi ...

  8. 【Luogu P3379】LCA问题的倍增解法

    Luogu P3379 题意:对于两个节点,寻找他们的最近公共祖先. 一个显而易见的解法是对于每一个节点我们都往上遍历一遍,记录下它每一个祖先,然后再从另一个节点出发,一步一步往上走,找到以前记录过第 ...

  9. day 27 网路编程 面向对象多继承

    知识补充: 字符串转化为字节 string1  = input(“请输入你的名字”) string1.encode('utf-8') 字节转化为字符串 byte1 = b"alex" ...

  10. at、crontab、anacron的基本使用

    Linux的任务调度机制主要分为两种: 1. 执行一次:将在某个特定的时间执行的任务调度 at 2. 执行多次: crontab 3.关机后恢复尚未执行的程序 anacron. ①at at命令用于在 ...