[修正]BufferedInputStream bufr = new BufferedInputStream(new FileInputStream("d:\\1.txt"));
现在的情况是这样的,从控制器搞来的InputStream我要读取里面的字节,假设142个字节为一条指令,我知道一共有32条指令就是4544个字节,但是通过 public void writeStoreData() throws IOException { int a = 0;//指令数 while (inputStream.available()>0){ storeData = new byte[inputStream.available()]; for (int i=0;i<inputStream.available();i++){ inputStream.read(storeData,i,142); //满足条件指令就累加 if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||){ a++; } } System.out.println(a); } } 按照理论讲inputstream.available()应该为4544但是我断点看了下实际只有4094,少了部分数据,结果指令只有29条了。。这要怎么办
使用缓冲区 byte[] vBuffer = new byte[2048]; int vReadCount = 0; while((vReadCount = vInputStream.read(vBuffer)) != -1){ vOutputStream.write(vbuffer, 0, vReadCount); }楼主有兴趣的话可以查一下inputStream/outPutStream 的api
public void writeStoreData() throws IOException { System.out.print("OK*********"); int a = 0; storeData = new byte[512*1024]; while (inputStream.read(storeData,i,142)!=-1){ if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||storeData[i+3]==104|| storeData[i+4]==1||storeData[i+5]==1){ a++; System.out.print(a+"*"); } i+=142; } outputStream.close(); inputStream.close(); } 刚改了下,不过也没什么用字节数组都512K了
岂不是后面的直接覆盖前面的?但又没有完全覆盖,每次都留1个字节,好吧,这个也不算是最大问题。比较有意思的问题是循环本身: for (int i=0;i<inputStream.available();i++) 假定inputStream.available()的预期值是4544,那么也就意味着你这个循环会循环 4544次,对吧? 但你每次要求读取142个字节,也就意味着你总共企图读取645248个字节。但是更有意思的是,其实随着你每次循环读取,你的inputStream.available()是在不断减少的,对吧? 也就是随着i的不断增加,你的i<inputStream.available()右边这个值却在不断减小,这个循环的效果就很动态化或者戏剧化了。所以我很想不通你究竟想实现什么效果另外还有个小问题是,你能确定 inputStream.read(storeData,i,142); 读取的都是142个字节长么?你的流是永不阻塞型的么?建议: int len = inputStream.read(storeData,i,142); 并把len打印出来,尤其是len!=142 的打印出来。
public void writeStoreData() throws IOException { System.out.print("OK*********"); int a = 0; storeData = new byte[512*1024]; while (inputStream.read(storeData,i,142)!=-1){ if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||storeData[i+3]==104|| storeData[i+4]==1||storeData[i+5]==1){ a++; System.out.print(a+"*"); } i+=142; } outputStream.close(); inputStream.close(); } 已经改过了,不会有留1个字节第一次存入(0~141)共142个之后是i+142开始.......你上面还是讲的还是挺有用的
看了半天是旧版本的,汗新版本的大逻辑上貌似没啥问题,唯一的漏洞就仅在:while (inputStream.read(storeData,i,142)!=-1) 这里了,因为read函数不保证一定完整读取142字节长;所以还是建议修改为: while ((len=(inputStream.read(storeData,i,142))!=-1) 然后 i+=len;
public boolean tranFile(File copy,File paste) throws IOException{
// System.out.println(paste.isFile()+"123");
// System.out.println(copy.isFile()+"456");
if(!copy.isFile()||paste.isFile())
return false;
if(!paste.exists())
paste.mkdirs();
try{
String separator="";
separator=System.getProperties().getProperty("file.separator");
System.out.println(paste.getPath());
System.out.println(copy.getName());
System.out.println(separator);
InputStream in=new FileInputStream(copy);
OutputStream out=new FileOutputStream(paste.getPath()+separator+copy.getName());
byte b[]=new byte[1024];
while(in.read(b,0,1024)!=-1)//这就是你要的重点了,这个read函数是每次读取1024个byte到b中,0的意思是从b[0]开始存数据
{
out.write(b);
}
in.close();
out.close();
}
catch(Exception e)
{
System.out.println("你输入paste目录有问题!");
return false;
}
return true;
}
BufferedInputStream bufr = new BufferedInputStream(new InputStream("d:\\1.txt"));
byte [] buf = new byte[1024*1024]; //每次读取1M,(这边好像不可太大)
int len = 0;
while((len=bufr.read(buf))!=-1)
{
//code
}
public void writeStoreData() throws IOException {
int a = 0;//指令数
while (inputStream.available()>0){
storeData = new byte[inputStream.available()];
for (int i=0;i<inputStream.available();i++){
inputStream.read(storeData,i,142);
//满足条件指令就累加
if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||){
a++;
}
}
System.out.println(a);
}
}
按照理论讲inputstream.available()应该为4544但是我断点看了下实际只有4094,少了部分数据,结果指令只有29条了。。这要怎么办
建议:
1.确认输入;
2.用debug逐行检查,看看是否有哪里的逻辑或数据出了问题
好像字节流不关闭会出现一些错误的吧
4K很小没什么关系的
大文件不是一般逐个逐个读入输出的吗?
FileInputStream in=new FileInputStream(f);
FileOutputStream out=new FileOutputStream(f2);
int temp=0;
while((temp=in.read())!=-1){
out.write(temp);
}
in.close();
out.close();
byte[] vBuffer = new byte[2048];
int vReadCount = 0;
while((vReadCount = vInputStream.read(vBuffer)) != -1){
vOutputStream.write(vbuffer, 0, vReadCount);
}楼主有兴趣的话可以查一下inputStream/outPutStream 的api
System.out.print("OK*********");
int a = 0;
storeData = new byte[512*1024];
while (inputStream.read(storeData,i,142)!=-1){
if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||storeData[i+3]==104||
storeData[i+4]==1||storeData[i+5]==1){
a++;
System.out.print(a+"*");
}
i+=142;
}
outputStream.close();
inputStream.close();
}
刚改了下,不过也没什么用字节数组都512K了
几千万个Byte?假设为5千万Byte,也就是这个数据需要50MB的内存空间才能正常存储(不算辅助空间的话)。
楼主够狠的啊,能确定需求真的必须这么玩么?最好重新审视需求。如果你确定必须这么玩的话,建议如下:
1、建立一个缓存数组,类似你代码中的storeData,容量不同太大,4096就好了;
2、建立ByteArrayOutputStream;
3、将所有批次读取的storeData数据直接写入ByteArrayOutputStream;
4、循环3完成后,所有数据就都在ByteArrayOutputStream里面了,你可以toByteArray()拿出来慢慢玩。最重要的:java虚拟机启动参数必须加上: -Xmx512m 否则必然OOM。
是说你6楼的代码么?你能解释下,你这句话中的i企图用来干什么的? “inputStream.read(storeData,i,142);”
for (int i=0;i<inputStream.available();i++)
假定inputStream.available()的预期值是4544,那么也就意味着你这个循环会循环 4544次,对吧?
但你每次要求读取142个字节,也就意味着你总共企图读取645248个字节。但是更有意思的是,其实随着你每次循环读取,你的inputStream.available()是在不断减少的,对吧?
也就是随着i的不断增加,你的i<inputStream.available()右边这个值却在不断减小,这个循环的效果就很动态化或者戏剧化了。所以我很想不通你究竟想实现什么效果另外还有个小问题是,你能确定 inputStream.read(storeData,i,142); 读取的都是142个字节长么?你的流是永不阻塞型的么?建议: int len = inputStream.read(storeData,i,142);
并把len打印出来,尤其是len!=142 的打印出来。
System.out.print("OK*********");
int a = 0;
storeData = new byte[512*1024];
while (inputStream.read(storeData,i,142)!=-1){
if (storeData[i]==104||storeData[i+1]==103||storeData[i+2]==43||storeData[i+3]==104||
storeData[i+4]==1||storeData[i+5]==1){
a++;
System.out.print(a+"*");
}
i+=142;
}
outputStream.close();
inputStream.close();
}
已经改过了,不会有留1个字节第一次存入(0~141)共142个之后是i+142开始.......你上面还是讲的还是挺有用的
看了半天是旧版本的,汗新版本的大逻辑上貌似没啥问题,唯一的漏洞就仅在:while (inputStream.read(storeData,i,142)!=-1) 这里了,因为read函数不保证一定完整读取142字节长;所以还是建议修改为:
while ((len=(inputStream.read(storeData,i,142))!=-1)
然后 i+=len;
inputStream.read(storeData,i,142))!=-1 流结尾,这个难道不报错吗?标准流读取写法:
int size = 0;
byte[] buf = new byte[142];
while((size = inputStream.read(buf)) != -1) {
// 流的处理 buf缓冲区可用数据部分为 - buf[0] ~ buf[size-1]
// 这里处理你的缓冲区
}
你是字符指令串吗? 好吧,假设你是字符式的指令List<String> commandList = new ArrayList<String>(512);
int size = 0;
byte[] buf = new byte[142];
while((size = inputStream.read(buf)) != -1) {
// 假设你的字符是String,其他指令可以自己构建一个指令对象
commandList.add(new String(buf,0,size));
}for(String command : commandList){
// 处理指令列表
}
// 指令结构
class Command {
public byte[] data;
public Command(byte[] data) {
this.data = data;
}
}// 处理代码
List<Command> commandList = new ArrayList<Command>(512);
int size = 0;
byte[] buf = new byte[142];
while((size = inputStream.read(buf)) != -1) {
byte[] data = new byte[size];
System.arraycopy(buf, 0, data, 0, size)
commandList.add(new Command(data));
}for(Command command : commandList){
// 处理指令列表
}
你仔细看API了没?inputStream.available只是告诉你缓存区现有可读字节,不是所有字节。
你把这4096个字节读了之后,再看inputStream.available 就能找到那剩下的29个了。
看了半天是旧版本的,汗新版本的大逻辑上貌似没啥问题,唯一的漏洞就仅在:while (inputStream.read(storeData,i,142)!=-1) 这里了,因为read函数不保证一定完整读取142字节长;所以还是建议修改为:
while ((len=(inputStream.read(storeData,i,142))!=-1)
然后 i+=len;
这位ldh911果然学识渊博,这几天已经从你的几个回答里受教了